@@ -17,6 +17,7 @@ INSERT INTO parallel_test (x) SELECT x FROM generate_series(1,100) AS x;
1717CREATE TEMP TABLE parallel_test_tmp AS (SELECT * FROM parallel_test);
1818VACUUM ANALYZE parallel_test, parallel_test_tmp;
1919SET tempscan.enable = 'on';
20+ SET tempscan.force = 'on';
2021EXPLAIN (COSTS OFF)
2122SELECT count(*) FROM parallel_test;
2223 QUERY PLAN
@@ -56,8 +57,8 @@ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test t2;
5657
5758EXPLAIN (COSTS OFF)
5859SELECT count(*) FROM parallel_test_tmp t1 NATURAL JOIN parallel_test t2;
59- QUERY PLAN
60- ----------------------------------------------------------------------
60+ QUERY PLAN
61+ ----------------------------------------------------------------------------
6162 Finalize Aggregate
6263 -> Gather
6364 Workers Planned: 1
@@ -66,9 +67,10 @@ SELECT count(*) FROM parallel_test_tmp t1 NATURAL JOIN parallel_test t2;
6667 Hash Cond: (t2.x = t1.x)
6768 -> Parallel Seq Scan on parallel_test t2
6869 -> Hash
69- -> Custom Scan (nodeCustomTempScan)
70- -> Seq Scan on parallel_test_tmp t1
71- (10 rows)
70+ -> Materialize
71+ -> Custom Scan (nodeCustomTempScan)
72+ -> Seq Scan on parallel_test_tmp t1
73+ (11 rows)
7274
7375-- Just see how merge join manages custom parallel scan path
7476SET enable_hashjoin = 'off';
@@ -92,8 +94,8 @@ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test t2;
9294
9395EXPLAIN (COSTS OFF)
9496SELECT count(*) FROM parallel_test_tmp t1 NATURAL JOIN parallel_test t2;
95- QUERY PLAN
96- ----------------------------------------------------------------------
97+ QUERY PLAN
98+ ----------------------------------------------------------------------------
9799 Finalize Aggregate
98100 -> Gather
99101 Workers Planned: 1
@@ -105,9 +107,10 @@ SELECT count(*) FROM parallel_test_tmp t1 NATURAL JOIN parallel_test t2;
105107 -> Parallel Seq Scan on parallel_test t2
106108 -> Sort
107109 Sort Key: t1.x
108- -> Custom Scan (nodeCustomTempScan)
109- -> Seq Scan on parallel_test_tmp t1
110- (13 rows)
110+ -> Materialize
111+ -> Custom Scan (nodeCustomTempScan)
112+ -> Seq Scan on parallel_test_tmp t1
113+ (14 rows)
111114
112115RESET enable_hashjoin;
113116-- Increase table size and see how indexes work
@@ -119,18 +122,20 @@ VACUUM ANALYZE;
119122EXPLAIN (COSTS OFF)
120123SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp t2
121124WHERE t1.x < 10;
122- QUERY PLAN
123- -----------------------------------------------------------------------------------------------
125+ QUERY PLAN
126+ ----------------------------------------------------------------------
124127 Aggregate
125128 -> Gather
126129 Workers Planned: 3
127- -> Nested Loop
130+ -> Hash Join
131+ Hash Cond: (t1.x = t2.x)
128132 -> Parallel Seq Scan on parallel_test t1
129133 Filter: (x < 10)
130- -> Custom Scan (nodeCustomTempScan)
131- -> Index Only Scan using parallel_test_tmp_x_idx on parallel_test_tmp t2
132- Index Cond: (x = t1.x)
133- (9 rows)
134+ -> Hash
135+ -> Materialize
136+ -> Custom Scan (nodeCustomTempScan)
137+ -> Seq Scan on parallel_test_tmp t2
138+ (11 rows)
134139
135140CREATE TEMP TABLE parallel_test_tmp_2 AS (SELECT * FROM parallel_test);
136141CREATE INDEX ON parallel_test_tmp_2 (x);
@@ -155,42 +160,61 @@ WHERE t2.x < 10;
155160EXPLAIN (COSTS OFF)
156161SELECT count(*) FROM parallel_test_tmp_2 t1 NATURAL JOIN parallel_test_tmp_2 t2
157162WHERE t1.x < 10;
158- QUERY PLAN
159- ----------------------------------------------------------------------------------------
163+ QUERY PLAN
164+ ----------------------------------------------------------------------------------------------
160165 Aggregate
161166 -> Nested Loop
162- -> Custom Scan (nodeCustomTempScan)
163- -> Index Scan using parallel_test_tmp_2_x_idx on parallel_test_tmp_2 t1
164- Index Cond: (x < 10)
165- -> Custom Scan (nodeCustomTempScan )
166- -> Index Scan using parallel_test_tmp_2_x_idx on parallel_test_tmp_2 t2
167- Index Cond: (x = t1.x)
168- Filter: (y = t1.y)
167+ -> Materialize
168+ -> Custom Scan (nodeCustomTempScan)
169+ -> Index Scan using parallel_test_tmp_2_x_idx on parallel_test_tmp_2 t1
170+ Index Cond: (x < 10 )
171+ -> Index Scan using parallel_test_tmp_2_x_idx on parallel_test_tmp_2 t2
172+ Index Cond: (x = t1.x)
173+ Filter: (y = t1.y)
169174(9 rows)
170175
171176-- Employ parallel join using CustomScan as an inner
172177EXPLAIN (COSTS OFF)
173178SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2
174- WHERE t1.x < 10;
175- QUERY PLAN
176- ----------------------------------------------------------------------------------------------
179+ WHERE t1.x < 10 AND t2.x < 10 ;
180+ QUERY PLAN
181+ ----------------------------------------------------------------------------------------------------------
177182 Aggregate
178183 -> Gather
179184 Workers Planned: 3
180- -> Nested Loop
185+ -> Hash Join
186+ Hash Cond: ((t1.x = t2.x) AND (t1.y = t2.y))
181187 -> Parallel Seq Scan on parallel_test t1
182188 Filter: (x < 10)
183- -> Custom Scan (nodeCustomTempScan)
184- -> Index Scan using parallel_test_tmp_2_x_idx on parallel_test_tmp_2 t2
185- Index Cond: (x = t1.x)
186- Filter: (t1.y = y)
187- (10 rows)
189+ -> Hash
190+ -> Materialize
191+ -> Custom Scan (nodeCustomTempScan)
192+ -> Index Scan using parallel_test_tmp_2_x_idx on parallel_test_tmp_2 t2
193+ Index Cond: (x < 10)
194+ (12 rows)
195+
196+ -- Parameterised NestLoop beats HashJoin. No ParallelTempScan possible
197+ EXPLAIN (COSTS OFF)
198+ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2
199+ WHERE t1.x < 10;
200+ QUERY PLAN
201+ ----------------------------------------------------------------------------------
202+ Aggregate
203+ -> Nested Loop
204+ -> Gather
205+ Workers Planned: 3
206+ -> Parallel Seq Scan on parallel_test t1
207+ Filter: (x < 10)
208+ -> Index Scan using parallel_test_tmp_2_x_idx on parallel_test_tmp_2 t2
209+ Index Cond: (x = t1.x)
210+ Filter: (t1.y = y)
211+ (9 rows)
188212
189213-- Check real execution
190214EXPLAIN (VERBOSE, COSTS OFF)
191215SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
192- QUERY PLAN
193- --------------------------------------------------------------------------
216+ QUERY PLAN
217+ --------------------------------------------------------------------------------
194218 Aggregate
195219 Output: count(*)
196220 -> Gather
@@ -201,11 +225,13 @@ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
201225 Output: t1.x, t1.y
202226 -> Hash
203227 Output: t2.x, t2.y
204- -> Custom Scan (nodeCustomTempScan)
228+ -> Materialize
205229 Output: t2.x, t2.y
206- -> Seq Scan on pg_temp.parallel_test_tmp_2 t2
230+ -> Custom Scan (nodeCustomTempScan)
207231 Output: t2.x, t2.y
208- (14 rows)
232+ -> Seq Scan on pg_temp.parallel_test_tmp_2 t2
233+ Output: t2.x, t2.y
234+ (16 rows)
209235
210236SET max_parallel_workers_per_gather = 0;
211237SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
@@ -217,8 +243,8 @@ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
217243SET max_parallel_workers_per_gather = 3;
218244EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF)
219245SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
220- QUERY PLAN
221- ----------------------------------------------------------------------------------------------
246+ QUERY PLAN
247+ ------------------------------------------------------------------------------------------------------
222248 Aggregate (actual rows=1 loops=1)
223249 -> Gather (actual rows=10100 loops=1)
224250 Workers Planned: 3
@@ -227,16 +253,18 @@ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
227253 Hash Cond: ((t1.x = t2.x) AND (t1.y = t2.y))
228254 -> Parallel Seq Scan on parallel_test t1 (actual rows=2525 loops=4)
229255 -> Hash (actual rows=10100 loops=4)
230- Buckets: 16384 Batches: 1 Memory Usage: 571kB
231- -> Custom Scan (nodeCustomTempScan) (actual rows=10100 loops=4)
232- -> Seq Scan on parallel_test_tmp_2 t2 (actual rows=10100 loops=1)
233- (11 rows)
256+ Buckets: 16384 (originally 4096) Batches: 1 (originally 1) Memory Usage: 571kB
257+ -> Materialize (actual rows=10100 loops=4)
258+ -> Custom Scan (nodeCustomTempScan) (actual rows=10100 loops=4)
259+ -> Seq Scan on parallel_test_tmp_2 t2 (actual rows=10100 loops=1)
260+ (12 rows)
234261
235262SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
236263 count
237264-------
238265 10100
239266(1 row)
240267
268+ RESET tempscan.force;
241269RESET tempscan.enable;
242270DROP TABLE parallel_test, parallel_test_tmp;
0 commit comments