Skip to content

Commit 3f90ec8

Browse files
committed
Postpone generate_gather_paths for topmost scan/join rel.
Don't call generate_gather_paths for the topmost scan/join relation when it is initially populated with paths. Instead, do the work in grouping_planner. By itself, this gains nothing; in fact it loses slightly because we end up calling set_cheapest() for the topmost scan/join rel twice rather than once. However, it paves the way for a future commit which will postpone generate_gather_paths for the topmost scan/join relation even further, allowing more accurate costing of parallel paths. Amit Kapila and Robert Haas. Earlier versions of this patch (which different substantially) were reviewed by Dilip Kumar, Amit Khandekar, Marina Polyakova, and Ashutosh Bapat.
1 parent d7c19e6 commit 3f90ec8

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

src/backend/optimizer/geqo/geqo_eval.c

+14-7
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ typedef struct
4040
} Clump;
4141

4242
static List *merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump,
43-
bool force);
43+
int num_gene, bool force);
4444
static bool desirable_join(PlannerInfo *root,
4545
RelOptInfo *outer_rel, RelOptInfo *inner_rel);
4646

@@ -196,7 +196,7 @@ gimme_tree(PlannerInfo *root, Gene *tour, int num_gene)
196196
cur_clump->size = 1;
197197

198198
/* Merge it into the clumps list, using only desirable joins */
199-
clumps = merge_clump(root, clumps, cur_clump, false);
199+
clumps = merge_clump(root, clumps, cur_clump, num_gene, false);
200200
}
201201

202202
if (list_length(clumps) > 1)
@@ -210,7 +210,7 @@ gimme_tree(PlannerInfo *root, Gene *tour, int num_gene)
210210
{
211211
Clump *clump = (Clump *) lfirst(lc);
212212

213-
fclumps = merge_clump(root, fclumps, clump, true);
213+
fclumps = merge_clump(root, fclumps, clump, num_gene, true);
214214
}
215215
clumps = fclumps;
216216
}
@@ -235,7 +235,8 @@ gimme_tree(PlannerInfo *root, Gene *tour, int num_gene)
235235
* "desirable" joins.
236236
*/
237237
static List *
238-
merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, bool force)
238+
merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, int num_gene,
239+
bool force)
239240
{
240241
ListCell *prev;
241242
ListCell *lc;
@@ -267,8 +268,14 @@ merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, bool force)
267268
/* Create paths for partitionwise joins. */
268269
generate_partitionwise_join_paths(root, joinrel);
269270

270-
/* Create GatherPaths for any useful partial paths for rel */
271-
generate_gather_paths(root, joinrel, false);
271+
/*
272+
* Except for the topmost scan/join rel, consider gathering
273+
* partial paths. We'll do the same for the topmost scan/join
274+
* rel once we know the final targetlist (see
275+
* grouping_planner).
276+
*/
277+
if (old_clump->size + new_clump->size < num_gene)
278+
generate_gather_paths(root, joinrel, false);
272279

273280
/* Find and save the cheapest paths for this joinrel */
274281
set_cheapest(joinrel);
@@ -286,7 +293,7 @@ merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, bool force)
286293
* others. When no further merge is possible, we'll reinsert
287294
* it into the list.
288295
*/
289-
return merge_clump(root, clumps, old_clump, force);
296+
return merge_clump(root, clumps, old_clump, num_gene, force);
290297
}
291298
}
292299
prev = lc;

src/backend/optimizer/path/allpaths.c

+19-7
Original file line numberDiff line numberDiff line change
@@ -479,13 +479,20 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
479479
}
480480

481481
/*
482-
* If this is a baserel, consider gathering any partial paths we may have
483-
* created for it. (If we tried to gather inheritance children, we could
482+
* If this is a baserel, we should normally consider gathering any partial
483+
* paths we may have created for it.
484+
*
485+
* However, if this is an inheritance child, skip it. Otherwise, we could
484486
* end up with a very large number of gather nodes, each trying to grab
485-
* its own pool of workers, so don't do this for otherrels. Instead,
486-
* we'll consider gathering partial paths for the parent appendrel.)
487+
* its own pool of workers. Instead, we'll consider gathering partial
488+
* paths for the parent appendrel.
489+
*
490+
* Also, if this is the topmost scan/join rel (that is, the only baserel),
491+
* we postpone this until the final scan/join targelist is available (see
492+
* grouping_planner).
487493
*/
488-
if (rel->reloptkind == RELOPT_BASEREL)
494+
if (rel->reloptkind == RELOPT_BASEREL &&
495+
bms_membership(root->all_baserels) != BMS_SINGLETON)
489496
generate_gather_paths(root, rel, false);
490497

491498
/*
@@ -2699,8 +2706,13 @@ standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
26992706
/* Create paths for partitionwise joins. */
27002707
generate_partitionwise_join_paths(root, rel);
27012708

2702-
/* Create GatherPaths for any useful partial paths for rel */
2703-
generate_gather_paths(root, rel, false);
2709+
/*
2710+
* Except for the topmost scan/join rel, consider gathering
2711+
* partial paths. We'll do the same for the topmost scan/join rel
2712+
* once we know the final targetlist (see grouping_planner).
2713+
*/
2714+
if (lev < levels_needed)
2715+
generate_gather_paths(root, rel, false);
27042716

27052717
/* Find and save the cheapest paths for this rel */
27062718
set_cheapest(rel);

src/backend/optimizer/plan/planner.c

+9
Original file line numberDiff line numberDiff line change
@@ -1974,6 +1974,15 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
19741974
scanjoin_targets = scanjoin_targets_contain_srfs = NIL;
19751975
}
19761976

1977+
/*
1978+
* Generate Gather or Gather Merge paths for the topmost scan/join
1979+
* relation. Once that's done, we must re-determine which paths are
1980+
* cheapest. (The previously-cheapest path might even have been
1981+
* pfree'd!)
1982+
*/
1983+
generate_gather_paths(root, current_rel, false);
1984+
set_cheapest(current_rel);
1985+
19771986
/*
19781987
* Forcibly apply SRF-free scan/join target to all the Paths for the
19791988
* scan/join rel.

0 commit comments

Comments
 (0)