pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Andrei Lepikhov <lepihov@gmail.com>
To: Ba Jinsheng <bajinsheng@u.nus.edu>
Cc: Tomas Vondra <tomas@vondra.me>
Cc: Zhang Mingli <zmlpostgres@gmail.com>
Cc: pgsql-bugs@lists.postgresql.org <pgsql-bugs@lists.postgresql.org>
Subject: Re: Question of Parallel Hash Join on TPC-H Benchmark
Date: Sun, 13 Oct 2024 10:09:29 +0700
Message-ID: <59f605ce-00f2-401b-be1e-5b684326ab6e@gmail.com> (raw)
In-Reply-To: <SEZPR06MB649483EF863B323B090986AD8A7A2@SEZPR06MB6494.apcprd06.prod.outlook.com>
References: <SEZPR06MB64945FE5A48A367A8C0EE8FC8A782@SEZPR06MB6494.apcprd06.prod.outlook.com>
	<SEZPR06MB6494C5B80077EC08B21772888A782@SEZPR06MB6494.apcprd06.prod.outlook.com>
	<20f9671d-6f40-429b-a749-a2f53086e0dd@vondra.me>
	<3c7df680-97e6-4f20-ab27-65fb8282f95e@Spark>
	<SEZPR06MB6494BD3DDF5B03700032C2C98A782@SEZPR06MB6494.apcprd06.prod.outlook.com>
	<978176f8-14a5-4f4d-8925-07d2e7dec4ce@gmail.com>
	<SEZPR06MB649483EF863B323B090986AD8A7A2@SEZPR06MB6494.apcprd06.prod.outlook.com>

On 13/10/2024 01:11, Ba Jinsheng wrote:
> I changed the code to generate an efficient query plan (only the 
> HashJoin in fifth line is in parallel), so I am wondering whether it is 
> possible to optimize the code to enable this efficient query plan in 
> default? I believe at least, it would improve the performance of 
> PostgreSQL on the standard benchmark TPC-H.
> If you need, I can provide my environment in docker for your analysis.
Thanks for the case! It was a pretty exciting case.

The answer to your question is simple: we have a correlated subquery 
here with the clause: 'p_partkey = ps_partkey'. Because of that, the top 
JOIN operator has parameterised inner, and parallel workers can't be 
used according to the current state of the code. See comments in the code:

/*
* If the inner path is parameterised, we can't use a partial hashjoin.
* Parameterised partial paths are not supported. The caller should
* already have verified that no lateral rels are required here.
*/

Even if you transform the subquery to SEMI JOIN, you will have a 
parameterised join, and the parallel plan will be declined.
So, the best you can do here is replace clause
'ps_supplycost = (SELECT ...)' with 'ps_supplycost IN (SELECT ...)'
I got quite a beneficial speedup there (see attached).

So, what can we improve here?
- I am suspicious about the parallel plans for parameterised paths, at 
least soon.
- Improve pull-ups for subqueries. Especially if we can prove that the 
subquery has a single aggregate returning only one tuple. It looks doable.

-- 
regards, Andrei Lepikhov

Attachments:

final_explain.txt (text/plain, 6.6K) download Limit (cost=612.17..10889.47 rows=100 width=192) (actual time=108.807..141.876 rows=100 loops=1) -> Incremental Sort (cost=612.17..20858.46 rows=197 width=192) (actual time=108.804..141.863 rows=100 loops=1) Sort Key: supplier.s_acctbal DESC, nation.n_name, supplier.s_name, part.p_partkey Presorted Key: supplier.s_acctbal, nation.n_name, supplier.s_name Full-sort Groups: 4 Sort Method: quicksort Average Memory: 33kB Peak Memory: 33kB -> Nested Loop (cost=508.91..20849.59 rows=197 width=192) (actual time=96.504..141.737 rows=101 loops=1) Join Filter: (supplier.s_suppkey = partsupp.ps_suppkey) Rows Removed by Join Filter: 209606 -> Gather Merge (cost=359.76..1005.71 rows=606 width=166) (actual time=10.099..10.312 rows=433 loops=1) Workers Planned: 5 Workers Launched: 5 -> Sort (cost=259.68..259.99 rows=121 width=166) (actual time=1.568..1.583 rows=72 loops=6) Sort Key: supplier.s_acctbal DESC, nation.n_name, supplier.s_name Sort Method: quicksort Memory: 422kB Worker 0: Sort Method: quicksort Memory: 25kB Worker 1: Sort Method: quicksort Memory: 25kB Worker 2: Sort Method: quicksort Memory: 25kB Worker 3: Sort Method: quicksort Memory: 25kB Worker 4: Sort Method: quicksort Memory: 25kB -> Parallel Hash Join (cost=2.30..255.50 rows=121 width=166) (actual time=0.066..1.085 rows=334 loops=6) Hash Cond: (supplier.s_nationkey = nation.n_nationkey) -> Parallel Seq Scan on supplier (cost=0.00..243.00 rows=2060 width=144) (actual time=0.005..2.074 rows=10000 loops=1) -> Parallel Hash (cost=2.27..2.27 rows=3 width=30) (actual time=0.042..0.043 rows=1 loops=6) Buckets: 1024 Batches: 1 Memory Usage: 40kB -> Parallel Hash Join (cost=1.05..2.27 rows=3 width=30) (actual time=0.089..0.124 rows=5 loops=1) Hash Cond: (nation.n_regionkey = region.r_regionkey) -> Parallel Seq Scan on nation (cost=0.00..1.15 rows=14 width=34) (actual time=0.004..0.008 rows=25 loops=1) -> Parallel Hash (cost=1.04..1.04 rows=1 width=4) (actual time=0.025..0.026 rows=1 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 40kB -> Parallel Seq Scan on region (cost=0.00..1.04 rows=1 width=4) (actual time=0.014..0.016 rows=1 loops=1) Filter: (r_name = 'ASIA'::bpchar) Rows Removed by Filter: 4 -> Materialize (cost=149.15..15436.44 rows=485 width=34) (actual time=0.002..0.234 rows=484 loops=433) Storage: Memory Maximum Storage: 51kB -> Nested Loop (cost=149.15..15434.02 rows=485 width=34) (actual time=0.846..84.831 rows=485 loops=1) -> Gather (cost=100.00..5421.00 rows=826 width=30) (actual time=0.412..20.567 rows=826 loops=1) Workers Planned: 8 Workers Launched: 3 -> Parallel Seq Scan on part (cost=0.00..4495.00 rows=103 width=30) (actual time=0.139..25.150 rows=206 loops=4) Filter: (((p_type)::text ~~ '%STEEL'::text) AND (p_size = 30)) Rows Removed by Filter: 49794 -> Hash Join (cost=49.15..61.20 rows=1 width=8) (actual time=0.073..0.074 rows=1 loops=826) Hash Cond: (partsupp.ps_supplycost = (min(partsupp_1.ps_supplycost))) -> Index Scan using partsupp_pkey on partsupp (cost=0.42..12.47 rows=4 width=14) (actual time=0.008..0.010 rows=4 loops=485) Index Cond: (ps_partkey = part.p_partkey) -> Hash (cost=48.71..48.71 rows=1 width=32) (actual time=0.064..0.064 rows=1 loops=826) Buckets: 1024 Batches: 1 Memory Usage: 9kB -> Aggregate (cost=48.70..48.71 rows=1 width=32) (actual time=0.063..0.063 rows=1 loops=826) -> Nested Loop (cost=0.85..48.70 rows=1 width=6) (actual time=0.046..0.059 rows=1 loops=826) Join Filter: (region_1.r_regionkey = nation_1.n_regionkey) Rows Removed by Join Filter: 3 -> Seq Scan on region region_1 (cost=0.00..1.06 rows=1 width=4) (actual time=0.003..0.004 rows=1 loops=826) Filter: (r_name = 'ASIA'::bpchar) Rows Removed by Filter: 4 -> Nested Loop (cost=0.85..47.59 rows=4 width=10) (actual time=0.021..0.054 rows=4 loops=826) -> Nested Loop (cost=0.71..46.96 rows=4 width=10) (actual time=0.017..0.038 rows=4 loops=826) -> Index Scan using partsupp_pkey on partsupp partsupp_1 (cost=0.42..13.75 rows=4 width=10) (actual time=0.010..0.012 rows=4 loops=826) Index Cond: (ps_partkey = part.p_partkey) -> Index Scan using supplier_pkey on supplier supplier_1 (cost=0.29..8.30 rows=1 width=8) (actual time=0.005..0.005 rows=1 loops=3304) Index Cond: (s_suppkey = partsupp_1.ps_suppkey) -> Index Scan using nation_pkey on nation nation_1 (cost=0.14..0.16 rows=1 width=8) (actual time=0.003..0.003 rows=1 loops=3304) Index Cond: (n_nationkey = supplier_1.s_nationkey) Planning Time: 14.975 ms Execution Time: 144.161 ms (64 rows)

view thread (12+ messages)  latest in thread

Message-ID: <59f605ce-00f2-401b-be1e-5b684326ab6e@gmail.com>
Permalink:  ../59f605ce-00f2-401b-be1e-5b684326ab6e@gmail.com/
Also on:    postgresql.org/message-id/59f605ce-00f2-401b-be1e-5b684326ab6e@gmail.com

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-bugs@postgresql.org
  Cc: lepihov@gmail.com, bajinsheng@u.nus.edu, tomas@vondra.me, zmlpostgres@gmail.com, pgsql-bugs@lists.postgresql.org
  Subject: Re: Question of Parallel Hash Join on TPC-H Benchmark
  In-Reply-To: <59f605ce-00f2-401b-be1e-5b684326ab6e@gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox