查询执行器 - 上一步的开始与下一步的结束不重叠



我查看了 Postgres 查询计划,我注意到上一步开始时间与下步结束时间不重叠,所以我想知道间隔时间花在哪里?

已为此查询编辑字段名称。

正如您在下面看到的,查询执行器有 2 个步骤。较低的步骤"索引扫描"在 5730.776(实际时间)结束,但根步骤从 19199.316(实际时间)开始。我的问题是 5730.776 到 19199.316 之间发生了什么?

邮政 9.1

explain analyze select a_id,b_id,c_id,d_id,e_id,mydate, f,sum(used) used
from report A where mydate >= '2013-05-01' and mydate  <= '2013-08-30'
group by a_id,b_id,c_id,d_id,e_id,date,f;
                                                                                                      QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 HashAggregate  (cost=412378.59..418074.28 rows=569569 width=70) (actual time=**19199.316**..25518.672 rows=4935988 loops=1)
   ->  Index Scan using report_dateonly_idx on report a  (cost=0.00..298464.83 rows=5695688 width=70) (actual time=0.033..**5730.776** rows=5816028 loops=1)
         Index Cond: ((date >= '2013-05-01 00:00:00'::timestamp without time zone) AND (date <= '2013-08-30 00:00:00'::timestamp without time zone))
 Total runtime: 29148.500 ms

你可能对有关了解查询计划的这一系列博客文章感兴趣。

在您的情况下,您误解了每个成本/时序中的两个数字所代表的含义。它们不是操作的开始和结束,而是(大致)第一行之前的成本/时间,以及包括所有行的成本/时间。

Depesz 举了一个排序操作的例子,"cost=22.88..23.61" - 准备数据的成本很高,因为你必须在返回任何数据之前对所有内容进行排序;实际返回它的成本要低得多,因为它只是通过排序列表进行假脱机。

所以在你的例子中,19199.316并不意味着哈希聚合直到t=19199.316

才开始运行,这意味着直到t=19199.316,哈希聚合不会有数据出来,因为它仍在准备东西。

事实上,一旦索引扫描开始返回数据,HashAggregate 就会开始处理数据,即 t=0.033;到 t=5730.776,索引扫描已经找到了所有相关行,但 HashAggregate 仍在处理它们。在 t=19199.316 时,HashAggregate 已准备好开始将数据返回给其父级(在本例中为最终结果),在 t=25518.672 时,它已完成返回它们。

Depezs还有一个工具,可以将查询计划解释为表格形式;这是你的计划。请注意,HashAggregate 显示的"独占时间"为 19787.896 - 这是进行哈希处理所花费的时间,忽略了输入数据的来源。

观察到的行为的原因:您的统计数据是错误的:

HashAggregate  (cost=412378.59..418074.28 rows=569569 width=70) (actual time=**19199.316**..25518.672 rows=4935988 loops=1)
 [expected] -----------------------------------^^^^^^       [actual rows found] > ------------------------ ^^^^^^^

这相差九倍,并导致计划者选择基于哈希表的聚合,因为它认为结果将适合work_mem。它最初尺寸过小,需要调整几次大小,如果不适合工作,它甚至必须溅到磁盘上。

顺便说一句:我无法重新创建这种计划。我不断收到位图索引扫描。

相关内容

最新更新