EXPLAIN for Postgres 병렬 쿼리에서 시간을 합산하는 방법

Nov 27 2020

EXPLAINPostgres 12.3에서 이것을 이해하는 데 문제가 있습니다 .

EXPLAIN (ANALYZE, VERBOSE, BUFFERS) SELECT count(1) FROM mytable WHERE page ~ 'foo';

16GB 메모리가있는 서버에서 3 천만 행이있는 22GB 테이블입니다. 쿼리는 7 개의 일치하는 행을 계산합니다.

출력을 I / O에 164 초가 소요되었다고 해석하지만 전체 쿼리에는 65 초 밖에 걸리지 않습니다. 일부 병렬 작업자를 이중으로 계산할 수 있다고 생각했지만을 추가해도 합산 VERBOSE되지 않는 것 같습니다.

2 명의 작업자 각각이 책을 읽는 데 약 55 초를 소비했다고 말하는 것 같습니다. 합계가 110 초인 경우 I / O 164 초를 얻으려면 어떻게해야합니까? (이 쿼리는 페이지가 캐시 될 때 ~ 10 초가 걸리기 때문에 실제 읽는 시간은 여기서 50 초에서 그리 멀지 않은 것으로 추측됩니다. FWIW)

나는 또한이 방법을 혼동하고있어 Parallel Seq Scan32초을 것 같다,하지만 최종 결과를 얻기 위해 왼쪽으로 또 다른 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

답변

1 LaurenzAlbe Nov 27 2020 at 14:21

parallel_leader_participation이 기본값 이므로 off리더는 순차 스캔에 참여합니다. 작업자 프로세스의 I / O 시간은 개별적으로 나열되지만 리더의 I / O 시간은 총 시간에서 작업자 시간을 빼서 만 찾을 수 있습니다.

병렬 순차 스캔은 거의 항상 65026.980 밀리 초가 걸렸습니다. 첫 번째 번호 (31764.552)는 시작 시간, 즉 첫 번째 결과 행이 반환 될 때까지 걸린 시간입니다. 여기에서 나를 놀라게하는 것이 있다면 그것은 높은 시작 시간입니다.