On Mon, 8 Jul 2024 at 15:43, David Rowley <dgrowle...@gmail.com> wrote:
>
> On Sun, 18 Feb 2024 at 11:31, Tomas Vondra
> <tomas.von...@enterprisedb.com> wrote:
> > 2) Leader vs. worker counters
> >
> > It seems to me this does nothing to add the per-worker values from "Heap
> > Blocks" into the leader, which means we get stuff like this:
> >
> >     Heap Blocks: exact=102 lossy=10995
> >     Worker 0:  actual time=50.559..209.773 rows=215253 loops=1
> >        Heap Blocks: exact=207 lossy=19354
> >     Worker 1:  actual time=50.543..211.387 rows=162934 loops=1
> >        Heap Blocks: exact=161 lossy=14636
> >
> > I think this is wrong / confusing, and inconsistent with what we do for
> > other nodes.
>
> Are you able to share which other nodes that you mean here?

I did the analysis on this and out of the node types that have
parallel instrumentation (per ExecParallelRetrieveInstrumentation()),
Parallel Hash is the only node that does anything different from the
others. Looking at the loop inside show_hash_info(), you can see it
takes the Max() of each property. There's some discussion in [1] about
why this came about. In particular [2].

I see no reason to copy the odd one out here, so I'm planning on going
ahead with the patch that has Bitmap Heap Scan copy what the majority
of other nodes do. I think we should consider aligning Parallel Hash
with the other Parallel node behaviour.

I've attached the (roughly done) schema and queries I used to obtain
the plans to do this analysis.

David

[1] 
https://www.postgresql.org/message-id/flat/20200323165059.GA24950%40alvherre.pgsql
[2] https://www.postgresql.org/message-id/31321.1586549487%40sss.pgh.pa.us
create table mill (a int);
create index on mill(a);

insert into mill select x%1000 from generate_Series(1,10000000)x;
vacuum analyze mill;

create table big (a int primary key);
insert into big select x from generate_series(1,10000000)x;
create table probe (a int);
insert into probe select 1 from generate_Series(1,1000000);
analyze big,probe;

create table agg (a int, b int);
insert into agg select a%1000,a from generate_Series(1,1000000)a;
create index on agg(a);

set parallel_tuple_cost=0;
set parallel_setup_cost=0;
set enable_indexscan=0;


-- each includes "Worker N:" with stats for the operation.
explain (analyze) select * from mill where a < 100; -- Bitmap Heap Scan
explain (analyze) select * from big b inner join probe p on b.a=p.a; -- Memoize
explain (analyze) select * from probe order by a; -- Sort
set enable_nestloop=0;
explain (analyze) select a,count(b) from agg group by a; -- HashAgg ODD ONE 
OUT. GETS MAX DETAILS FROM WORKERS.
explain (analyze) select * from big b inner join probe p on b.a=p.a; -- Hash
reset enable_nestloop;

set enable_indexscan=1; set enable_bitmapscan=0; set enable_seqscan=0;
explain (analyze) select a,b from agg where a > 10 order by a,b; -- Incremental 
Sort
set enable_indexscan=0; set enable_bitmapscan=1; set enable_seqscan=1;


-- each includes "Worker N:" with stats for the operation
-- also includes actual time and rows for each worker.
explain (analyze, verbose) select * from mill where a < 100; -- Bitmap Heap Scan
explain (analyze, verbose) select * from big b inner join probe p on b.a=p.a; 
-- Memoize
explain (analyze, verbose) select * from probe order by a; -- Sort
set enable_nestloop=0;
explain (analyze, verbose) select a,count(b) from agg group by a; -- HashAgg 
ODD ONE OUT. GETS MAX DETAILS FROM WORKERS.
explain (analyze, verbose) select * from big b inner join probe p on b.a=p.a; 
-- Hash
reset enable_nestloop;

set enable_indexscan=1; set enable_bitmapscan=0; set enable_seqscan=0;
explain (analyze, verbose) select a,b from agg where a > 10 order by a,b; -- 
Incremental Sort
set enable_indexscan=0; set enable_bitmapscan=1; set enable_seqscan=1;


-- each includes "Worker N:" with stats for the operation
-- shows a single total buffers which includes leader and worker buffers.
explain (analyze, buffers) select * from mill where a < 100; -- Bitmap Heap Scan
explain (analyze, buffers) select * from big b inner join probe p on b.a=p.a; 
-- Memoize
explain (analyze, buffers) select * from probe order by a; -- Sort
set enable_nestloop=0;
explain (analyze, buffers) select a,count(b) from agg group by a; -- HashAgg 
ODD ONE OUT. GETS MAX DETAILS FROM WORKERS.
reset enable_nestloop;

set enable_indexscan=1; set enable_bitmapscan=0; set enable_seqscan=0;
explain (analyze, buffers) select a,b from agg where a > 10 order by a,b; -- 
Incremental Sort
set enable_indexscan=0; set enable_bitmapscan=1; set enable_seqscan=1;


-- each includes "Worker N:" with stats for the operation
-- also includes actual time and rows for each worker.
-- shows a single total buffers which includes leader and worker buffers.
-- shows buffer counts for each worker process
explain (analyze, buffers, verbose) select * from mill where a < 100; -- Bitmap 
Heap Scan
explain (analyze, buffers, verbose) select * from big b inner join probe p on 
b.a=p.a;
explain (analyze, buffers, verbose) select * from probe order by a; -- Sort
set enable_nestloop=0;
explain (analyze, buffers, verbose) select a,count(b) from agg group by a; -- 
HashAgg ODD ONE OUT. GETS MAX DETAILS FROM WORKERS.
reset enable_nestloop;

set enable_indexscan=1; set enable_bitmapscan=0; set enable_seqscan=0;
explain (analyze, buffers, verbose) select a,b from agg where a > 10 order by 
a,b; -- Incremental Sort
set enable_indexscan=0; set enable_bitmapscan=1; set enable_seqscan=1;

Reply via email to