PostgreSQL码农集散地

PostgreSQL 18 preview - explain 增强 window 函数使用输出信息

PostgreSQL 18 preview - explain 增强 window 函数使用输出信息

PostgreSQL 18 explain 增强 window 函数使用输出信息, 在结果中输出窗口的内容. 之前,EXPLAIN 命令在显示查询计划时,对于窗口函数的定义只是简单地显示为 "OVER (?)",没有提供关于窗口函数具体定义的任何信息。这使得理解查询计划中窗口函数的使用变得困难。

改进后如下:

+-- Check expansion of window definitions  
+select explain_filter('explain verbose select sum(unique1) over w, sum(unique2) over (w order by hundred), sum(tenthous) over (w order by hundred) from tenk1 window w as (partition by ten)');  
+                                            explain_filter                                               
+-------------------------------------------------------------------------------------------------------  
+ WindowAgg  (cost=N.N..N.N rows=N width=N)  
+   Output: sum(unique1) OVER w, (sum(unique2) OVER w1), (sum(tenthous) OVER w1), ten, hundred  
+   Window: w AS (PARTITION BY tenk1.ten)  
+   ->  WindowAgg  (cost=N.N..N.N rows=N width=N)  
+         Output: ten, hundred, unique1, unique2, tenthous, sum(unique2) OVER w1, sum(tenthous) OVER w1  
+         Window: w1 AS (PARTITION BY tenk1.ten ORDER BY tenk1.hundred)  
+         ->  Sort  (cost=N.N..N.N rows=N width=N)  
+               Output: ten, hundred, unique1, unique2, tenthous  
+               Sort Key: tenk1.ten, tenk1.hundred  
+               ->  Seq Scan on public.tenk1  (cost=N.N..N.N rows=N width=N)  
+                     Output: ten, hundred, unique1, unique2, tenthous  
+(11 rows)  
+  
+select explain_filter('explain verbose select sum(unique1) over w1, sum(unique2) over (w1 order by hundred), sum(tenthous) over (w1 order by hundred rows 10 preceding) from tenk1 window w1 as (partition by ten)');  
+                                             explain_filter                                                
+---------------------------------------------------------------------------------------------------------  
+ WindowAgg  (cost=N.N..N.N rows=N width=N)  
+   Output: sum(unique1) OVER w1, (sum(unique2) OVER w2), (sum(tenthous) OVER w3), ten, hundred  
+   Window: w1 AS (PARTITION BY tenk1.ten)  
+   ->  WindowAgg  (cost=N.N..N.N rows=N width=N)  
+         Output: ten, hundred, unique1, unique2, tenthous, (sum(unique2) OVER w2), sum(tenthous) OVER w3  
+         Window: w3 AS (PARTITION BY tenk1.ten ORDER BY tenk1.hundred ROWS 'N'::bigint PRECEDING)  
+         ->  WindowAgg  (cost=N.N..N.N rows=N width=N)  
+               Output: ten, hundred, unique1, unique2, tenthous, sum(unique2) OVER w2  
+               Window: w2 AS (PARTITION BY tenk1.ten ORDER BY tenk1.hundred)  
+               ->  Sort  (cost=N.N..N.N rows=N width=N)  
+                     Output: ten, hundred, unique1, unique2, tenthous  
+                     Sort Key: tenk1.ten, tenk1.hundred  
+                     ->  Seq Scan on public.tenk1  (cost=N.N..N.N rows=N width=N)  
+                           Output: ten, hundred, unique1, unique2, tenthous  
+(14 rows)  

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=8b1b342544b69b281ffd3aafe594aec629ec4d3c

Improve EXPLAIN's display of window functions.  
author Tom Lane <[email protected]>   
Tue, 11 Mar 2025 15:19:54 +0000 (11:19 -0400)  
committer Tom Lane <[email protected]>   
Tue, 11 Mar 2025 15:19:54 +0000 (11:19 -0400)  
commit 8b1b342544b69b281ffd3aafe594aec629ec4d3c  
tree 6239ec69a949ffb5397fc4f7a5f50128d446d477 tree  
parent 426ea611171da4e60ab4f3863fa3cc3683ae9547 commit | diff  
Improve EXPLAIN'
s display of window functions.  

Up to now we just punted on showing the window definitions used  
in a plan, with window function calls represented as "OVER (?)".  
To improve that, show the window definition implemented by each  
WindowAgg plan node, and reference their window names in OVER.  
For nameless window clauses generated by "OVER (...)", assign  
unique names w1, w2, etc.  

In passing, re-order the properties shown for a WindowAgg node  
so that the Run Condition (if any) appears after the Window  
property and before the Filter (if any).  This seems more  
sensible since the Run Condition is associated with the Window  
and acts before the Filter.  

Thanks to David G. Johnston and Álvaro Herrera for design  
suggestions.  

Author: Tom Lane <[email protected]>  
Reviewed-by: David Rowley <[email protected]>  
Discussion: https://postgr.es/m/[email protected]  

AI解读如下

这个补丁改进了 EXPLAIN 命令对窗口函数的显示方式。

背景:

之前,EXPLAIN 命令在显示查询计划时,对于窗口函数的定义只是简单地显示为 "OVER (?)",没有提供关于窗口函数具体定义的任何信息。这使得理解查询计划中窗口函数的使用变得困难。

改进:

这个补丁做了以下改进:

  1. 显示窗口定义:  对于每个 WindowAgg 计划节点(负责执行窗口函数的节点),EXPLAIN 现在会显示该节点实现的窗口定义。这意味着你可以看到窗口函数的 PARTITION BY、ORDER BY、ROWS 或 RANGE 子句等信息。

  2. 引用窗口名称:  在 OVER 子句中,现在会引用窗口的名称。  如果窗口子句没有显式命名(例如 OVER (PARTITION BY ...)),则会自动分配唯一的名称,如 w1、w2 等。  这样可以更清晰地识别和区分不同的窗口函数。

  3. 重新排序属性显示:WindowAgg 节点的属性显示顺序被调整。  Run Condition(如果有)现在会显示在 Window 属性之后,Filter 属性之前。  这样做更合理,因为 Run Condition 与 Window 相关联,并且在 Filter 之前起作用。

总结:

总而言之,这个补丁通过提供更详细的窗口函数定义信息,以及更清晰的窗口名称引用,显著提高了 EXPLAIN 命令对窗口函数查询计划的可读性和理解性。  这使得开发人员和数据库管理员更容易分析和优化包含窗口函数的查询。

例子:

假设之前的 EXPLAIN 输出对于一个包含窗口函数的查询,可能显示如下:

->  WindowAgg  (cost=...)  
      Functions: row_number() OVER (?)  

应用这个补丁后,输出可能会变成这样:

->  WindowAgg  (cost=...)  
      Window [w1]: partition by (column1) order by (column2)  
      Run Condition: ...  
      Functions: row_number() OVER (w1)  

或者,如果窗口函数有显式名称:

->  WindowAgg  (cost=...)  
      Window [my_window]: partition by (column1) order by (column2)  
      Run Condition: ...  
      Functions: row_number() OVER (my_window)