我EXPLAIN
在 Postgres 12.3 上无法理解这一点:
EXPLAIN (ANALYZE, VERBOSE, BUFFERS) SELECT count(1) FROM mytable WHERE page ~ 'foo';
这是一个包含 3000 万行的 22GB 表,位于具有 16GB 内存的服务器上。该查询计算 7 个匹配行。
我将输出解释为 I/O 花费了 164 秒,但整个查询只用了 65 秒。我认为这可能会重复计算一些并行工作人员,但是当我添加时VERBOSE
,它似乎也没有加起来。
看起来好像是说 2 名工人中的每一个都花了大约 55 秒的时间阅读。如果总和为 110 秒,我如何获得 164 秒的 I/O?(由于缓存页面时此查询需要约 10 秒,我猜实际读取时间与此处的 50 秒相差不远,FWIW)
我也很困惑这Parallel Seq Scan
似乎需要 32 秒,但还有 30 多秒才能得到最终结果。我认为由于它找到了 7 行,除了扫描之外几乎没有其他工作可做。我读错了这个部分吗?
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=3092377.14..3092377.15 rows=1 width=8) (actual time=65028.818..65028.818 rows=1 loops=1)
Output: count(1)
Buffers: shared hit=75086 read=2858433 dirtied=1
I/O Timings: read=164712.060
-> Gather (cost=3092376.92..3092377.13 rows=2 width=8) (actual time=65028.732..65030.093 rows=3 loops=1)
Output: (PARTIAL count(1))
Workers Planned: 2
Workers Launched: 2
Buffers: shared hit=75086 read=2858433 dirtied=1
I/O Timings: read=164712.060
-> Partial Aggregate (cost=3091376.92..3091376.93 rows=1 width=8) (actual time=65026.990..65026.990 rows=1 loops=3)
Output: PARTIAL count(1)
Buffers: shared hit=75086 read=2858433 dirtied=1
I/O Timings: read=164712.060
Worker 0: actual time=65026.164..65026.164 rows=1 loops=1
Buffers: shared hit=25002 read=952587
I/O Timings: read=54906.994
Worker 1: actual time=65026.264..65026.264 rows=1 loops=1
Buffers: shared hit=25062 read=954370 dirtied=1
I/O Timings: read=54889.244
-> Parallel Seq Scan on public.ui_events_v2 (cost=0.00..3091374.68 rows=896 width=0) (actual time=31764.552..65026.980 rows=2 loops=3)
Filter: (ui_events_v2.page ~ 'foo'::text)
Rows Removed by Filter: 10112272
Buffers: shared hit=75086 read=2858433 dirtied=1
I/O Timings: read=164712.060
Worker 0: actual time=16869.988..65026.156 rows=2 loops=1
Buffers: shared hit=25002 read=952587
I/O Timings: read=54906.994
Worker 1: actual time=64091.539..65026.258 rows=1 loops=1
Buffers: shared hit=25062 read=954370 dirtied=1
I/O Timings: read=54889.244
Planning Time: 0.333 ms
Execution Time: 65030.133 ms
由于
parallel_leader_participation
是默认值off
,领导者参与顺序扫描。worker进程的I/O时间是单独列出的,但是leader的I/O时间只能通过总时间减去worker的时间才能得到。并行顺序扫描花费了 65026.980 毫秒,几乎所有时间。第一个数字 (31764.552) 是启动时间,即返回第一个结果行所用的时间。如果有什么让我感到惊讶的话,那就是启动时间太长了。