Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit88ba0ae

Browse files
committed
Consider Parallel Append of partial paths for UNION [ALL].
Without this patch, we can implement a UNION or UNION ALL as anAppend where Gather appears beneath one or more of the Appendbranches, but this lets us put the Gather node on top, witha partial path for each relation underneath.There is considerably more work that could be done to improveplanning in this area, but that will probably need to waitfor a future release.Patch by me, reviewed and tested by Ashutosh Bapat and RajkumarRaghuwanshi.Discussion:http://postgr.es/m/CA+TgmoaLRAOqHmMZx=ESM3VDEPceg+-XXZsRXQ8GtFJO_zbMSw@mail.gmail.com
1 parent7c91a03 commit88ba0ae

File tree

1 file changed

+91
-2
lines changed

1 file changed

+91
-2
lines changed

‎src/backend/optimizer/prep/prepunion.c

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,18 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
298298
*/
299299
set_subquery_size_estimates(root,rel);
300300

301+
/*
302+
* Since we may want to add a partial path to this relation, we must
303+
* set its consider_parallel flag correctly.
304+
*/
305+
final_rel=fetch_upper_rel(subroot,UPPERREL_FINAL,NULL);
306+
rel->consider_parallel=final_rel->consider_parallel;
307+
301308
/*
302309
* For the moment, we consider only a single Path for the subquery.
303310
* This should change soon (make it look more like
304311
* set_subquery_pathlist).
305312
*/
306-
final_rel=fetch_upper_rel(subroot,UPPERREL_FINAL,NULL);
307313
subpath=get_cheapest_fractional_path(final_rel,
308314
root->tuple_fraction);
309315

@@ -320,6 +326,23 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
320326

321327
add_path(rel,path);
322328

329+
/*
330+
* If we have a partial path for the child relation, we can use that
331+
* to build a partial path for this relation. But there's no point in
332+
* considering any path but the cheapest.
333+
*/
334+
if (final_rel->partial_pathlist!=NIL)
335+
{
336+
Path*partial_subpath;
337+
Path*partial_path;
338+
339+
partial_subpath=linitial(final_rel->partial_pathlist);
340+
partial_path= (Path*)
341+
create_subqueryscan_path(root,rel,partial_subpath,
342+
NIL,NULL);
343+
add_partial_path(rel,partial_path);
344+
}
345+
323346
/*
324347
* Estimate number of groups if caller wants it. If the subquery used
325348
* grouping or aggregation, its output is probably mostly unique
@@ -552,6 +575,9 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root,
552575
doublesave_fraction=root->tuple_fraction;
553576
ListCell*lc;
554577
List*pathlist=NIL;
578+
List*partial_pathlist=NIL;
579+
boolpartial_paths_valid= true;
580+
boolconsider_parallel= true;
555581
List*rellist;
556582
List*tlist_list;
557583
List*tlist;
@@ -591,18 +617,34 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root,
591617

592618
*pTargetList=tlist;
593619

594-
/* Build pathlist and relid set. */
620+
/* Build pathlists and relid set. */
595621
foreach(lc,rellist)
596622
{
597623
RelOptInfo*rel=lfirst(lc);
598624

599625
pathlist=lappend(pathlist,rel->cheapest_total_path);
626+
627+
if (consider_parallel)
628+
{
629+
if (!rel->consider_parallel)
630+
{
631+
consider_parallel= false;
632+
partial_paths_valid= false;
633+
}
634+
elseif (rel->partial_pathlist==NIL)
635+
partial_paths_valid= false;
636+
else
637+
partial_pathlist=lappend(partial_pathlist,
638+
linitial(rel->partial_pathlist));
639+
}
640+
600641
relids=bms_union(relids,rel->relids);
601642
}
602643

603644
/* Build result relation. */
604645
result_rel=fetch_upper_rel(root,UPPERREL_SETOP,relids);
605646
result_rel->reltarget=create_pathtarget(root,tlist);
647+
result_rel->consider_parallel=consider_parallel;
606648

607649
/*
608650
* Append the child results together.
@@ -626,6 +668,53 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root,
626668
*/
627669
result_rel->rows=path->rows;
628670

671+
/*
672+
* Now consider doing the same thing using the partial paths plus Append
673+
* plus Gather.
674+
*/
675+
if (partial_paths_valid)
676+
{
677+
Path*ppath;
678+
ListCell*lc;
679+
intparallel_workers=0;
680+
681+
/* Find the highest number of workers requested for any subpath. */
682+
foreach(lc,partial_pathlist)
683+
{
684+
Path*path=lfirst(lc);
685+
686+
parallel_workers=Max(parallel_workers,path->parallel_workers);
687+
}
688+
Assert(parallel_workers>0);
689+
690+
/*
691+
* If the use of parallel append is permitted, always request at least
692+
* log2(# of children) paths. We assume it can be useful to have
693+
* extra workers in this case because they will be spread out across
694+
* the children. The precise formula is just a guess; see
695+
* add_paths_to_append_rel.
696+
*/
697+
if (enable_parallel_append)
698+
{
699+
parallel_workers=Max(parallel_workers,
700+
fls(list_length(partial_pathlist)));
701+
parallel_workers=Min(parallel_workers,
702+
max_parallel_workers_per_gather);
703+
}
704+
Assert(parallel_workers>0);
705+
706+
ppath= (Path*)
707+
create_append_path(result_rel,NIL,partial_pathlist,
708+
NULL,parallel_workers,enable_parallel_append,
709+
NIL,-1);
710+
ppath= (Path*)
711+
create_gather_path(root,result_rel,ppath,
712+
result_rel->reltarget,NULL,NULL);
713+
if (!op->all)
714+
ppath=make_union_unique(op,ppath,tlist,root);
715+
add_path(result_rel,ppath);
716+
}
717+
629718
/* Undo effects of possibly forcing tuple_fraction to 0 */
630719
root->tuple_fraction=save_fraction;
631720

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp