(2019/02/26 21:25), Etsuro Fujita wrote: > While working on [1], I noticed $Subject, that is: > > /* > * If we have grouping or aggregation to do, the topmost scan/join > * plan node must emit what the grouping step wants; otherwise, it > * should emit grouping_target. > */ > have_grouping = (parse->groupClause || parse->groupingSets || > parse->hasAggs || root->hasHavingQual); > if (have_grouping) > { > scanjoin_target = make_group_input_target(root, final_target); > --> scanjoin_target_parallel_safe = > is_parallel_safe(root, (Node *) grouping_target->exprs); > } > else > { > scanjoin_target = grouping_target; > scanjoin_target_parallel_safe = grouping_target_parallel_safe; > } > > The parallel safety of the final scan/join target is determined from the > grouping target, not that target, which would cause to generate inferior > parallel plans as shown below: > > pgbench=# explain verbose select aid+bid, sum(abalance), random() from > pgbench_accounts group by aid+bid; > QUERY PLAN > ------------------------------------------------------------------------------------------------------------ > GroupAggregate (cost=137403.01..159903.01 rows=1000000 width=20) > Output: ((aid + bid)), sum(abalance), random() > Group Key: ((pgbench_accounts.aid + pgbench_accounts.bid)) > -> Sort (cost=137403.01..139903.01 rows=1000000 width=8) > Output: ((aid + bid)), abalance > Sort Key: ((pgbench_accounts.aid + pgbench_accounts.bid)) > -> Gather (cost=10.00..24070.67 rows=1000000 width=8) > Output: (aid + bid), abalance > Workers Planned: 2 > -> Parallel Seq Scan on public.pgbench_accounts > (cost=0.00..20560.67 rows=416667 width=12) > Output: aid, bid, abalance > (11 rows) > > The final scan/join target {(aid + bid), abalance} is definitely > parallel safe, but the target evaluation isn't parallelized across > workers, which is not good. Attached is a patch for fixing this.
I added this to the upcoming commitfest. Best regards, Etsuro Fujita