@@ -17,6 +17,7 @@ INSERT INTO parallel_test (x) SELECT x FROM generate_series(1,100) AS x;
17
17
CREATE TEMP TABLE parallel_test_tmp AS (SELECT * FROM parallel_test);
18
18
VACUUM ANALYZE parallel_test, parallel_test_tmp;
19
19
SET tempscan.enable = 'on';
20
+ SET tempscan.force = 'on';
20
21
EXPLAIN (COSTS OFF)
21
22
SELECT count(*) FROM parallel_test;
22
23
QUERY PLAN
@@ -56,8 +57,8 @@ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test t2;
56
57
57
58
EXPLAIN (COSTS OFF)
58
59
SELECT count(*) FROM parallel_test_tmp t1 NATURAL JOIN parallel_test t2;
59
- QUERY PLAN
60
- ----------------------------------------------------------------------
60
+ QUERY PLAN
61
+ ----------------------------------------------------------------------------
61
62
Finalize Aggregate
62
63
-> Gather
63
64
Workers Planned: 1
@@ -66,9 +67,10 @@ SELECT count(*) FROM parallel_test_tmp t1 NATURAL JOIN parallel_test t2;
66
67
Hash Cond: (t2.x = t1.x)
67
68
-> Parallel Seq Scan on parallel_test t2
68
69
-> 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)
72
74
73
75
-- Just see how merge join manages custom parallel scan path
74
76
SET enable_hashjoin = 'off';
@@ -92,8 +94,8 @@ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test t2;
92
94
93
95
EXPLAIN (COSTS OFF)
94
96
SELECT count(*) FROM parallel_test_tmp t1 NATURAL JOIN parallel_test t2;
95
- QUERY PLAN
96
- ----------------------------------------------------------------------
97
+ QUERY PLAN
98
+ ----------------------------------------------------------------------------
97
99
Finalize Aggregate
98
100
-> Gather
99
101
Workers Planned: 1
@@ -105,9 +107,10 @@ SELECT count(*) FROM parallel_test_tmp t1 NATURAL JOIN parallel_test t2;
105
107
-> Parallel Seq Scan on parallel_test t2
106
108
-> Sort
107
109
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)
111
114
112
115
RESET enable_hashjoin;
113
116
-- Increase table size and see how indexes work
@@ -119,18 +122,20 @@ VACUUM ANALYZE;
119
122
EXPLAIN (COSTS OFF)
120
123
SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp t2
121
124
WHERE t1.x < 10;
122
- QUERY PLAN
123
- -----------------------------------------------------------------------------------------------
125
+ QUERY PLAN
126
+ ----------------------------------------------------------------------
124
127
Aggregate
125
128
-> Gather
126
129
Workers Planned: 3
127
- -> Nested Loop
130
+ -> Hash Join
131
+ Hash Cond: (t1.x = t2.x)
128
132
-> Parallel Seq Scan on parallel_test t1
129
133
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)
134
139
135
140
CREATE TEMP TABLE parallel_test_tmp_2 AS (SELECT * FROM parallel_test);
136
141
CREATE INDEX ON parallel_test_tmp_2 (x);
@@ -155,42 +160,61 @@ WHERE t2.x < 10;
155
160
EXPLAIN (COSTS OFF)
156
161
SELECT count(*) FROM parallel_test_tmp_2 t1 NATURAL JOIN parallel_test_tmp_2 t2
157
162
WHERE t1.x < 10;
158
- QUERY PLAN
159
- ----------------------------------------------------------------------------------------
163
+ QUERY PLAN
164
+ ----------------------------------------------------------------------------------------------
160
165
Aggregate
161
166
-> Nested Loop
162
- ->Custom Scan (nodeCustomTempScan)
163
- ->Index Scanusing parallel_test_tmp_2_x_idx on parallel_test_tmp_2 t1
164
- IndexCond: (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
+ -> IndexScan 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)
169
174
(9 rows)
170
175
171
176
-- Employ parallel join using CustomScan as an inner
172
177
EXPLAIN (COSTS OFF)
173
178
SELECT 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
+ ----------------------------------------------------------------------------------------------------------
177
182
Aggregate
178
183
-> Gather
179
184
Workers Planned: 3
180
- -> Nested Loop
185
+ -> Hash Join
186
+ Hash Cond: ((t1.x = t2.x) AND (t1.y = t2.y))
181
187
-> Parallel Seq Scan on parallel_test t1
182
188
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)
188
212
189
213
-- Check real execution
190
214
EXPLAIN (VERBOSE, COSTS OFF)
191
215
SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
192
- QUERY PLAN
193
- --------------------------------------------------------------------------
216
+ QUERY PLAN
217
+ --------------------------------------------------------------------------------
194
218
Aggregate
195
219
Output: count(*)
196
220
-> Gather
@@ -201,11 +225,13 @@ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
201
225
Output: t1.x, t1.y
202
226
-> Hash
203
227
Output: t2.x, t2.y
204
- ->Custom Scan (nodeCustomTempScan)
228
+ ->Materialize
205
229
Output: t2.x, t2.y
206
- ->Seq Scanon pg_temp.parallel_test_tmp_2 t2
230
+ ->Custom Scan(nodeCustomTempScan)
207
231
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)
209
235
210
236
SET max_parallel_workers_per_gather = 0;
211
237
SELECT 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;
217
243
SET max_parallel_workers_per_gather = 3;
218
244
EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF)
219
245
SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
220
- QUERY PLAN
221
- ----------------------------------------------------------------------------------------------
246
+ QUERY PLAN
247
+ ------------------------------------------------------------------------------------------------------
222
248
Aggregate (actual rows=1 loops=1)
223
249
-> Gather (actual rows=10100 loops=1)
224
250
Workers Planned: 3
@@ -227,16 +253,18 @@ SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
227
253
Hash Cond: ((t1.x = t2.x) AND (t1.y = t2.y))
228
254
-> Parallel Seq Scan on parallel_test t1 (actual rows=2525 loops=4)
229
255
-> 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)
234
261
235
262
SELECT count(*) FROM parallel_test t1 NATURAL JOIN parallel_test_tmp_2 t2;
236
263
count
237
264
-------
238
265
10100
239
266
(1 row)
240
267
268
+ RESET tempscan.force;
241
269
RESET tempscan.enable;
242
270
DROP TABLE parallel_test, parallel_test_tmp;