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

Commit992b5ba

Browse files
committed
Push scan/join target list beneath Gather when possible.
This means that, for example, "SELECT expensive_func(a) FROM bigtabWHERE something" can compute expensive_func(a) in the workers ratherthan the leader if it happens to be parallel-safe, which figures to bea big win in some practical cases.Currently, we can only do this if the entire target list isparallel-safe. If we worked harder, we might be able to evaluateparallel-safe targets in the worker and any parallel-restrictedtargets in the leader, but that would be more complicated, and therearen't that many parallel-restricted functions that people are likelyto use in queries anyway. I think. So just do the simple thing forthe moment.Robert Haas, Amit Kapila, and Tom Lane
1 parent2d8a1e2 commit992b5ba

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

‎src/backend/optimizer/plan/createplan.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,18 +1396,21 @@ create_projection_plan(PlannerInfo *root, ProjectionPath *best_path)
13961396
tlist=build_path_tlist(root,&best_path->path);
13971397

13981398
/*
1399-
* Although the ProjectionPath node wouldn't have been made unless its
1400-
* pathtarget is different from the subpath's, it can still happen that
1401-
* the constructed tlist matches the subplan's. (An example is that
1402-
* MergeAppend doesn't project, so we would have thought that we needed a
1403-
* projection to attach resjunk sort columns to its output ... but
1404-
* create_merge_append_plan might have added those same resjunk sort
1405-
* columns to both MergeAppend and its children.) So, if the desired
1406-
* tlist is the same expression-wise as the subplan's, just jam it in
1407-
* there. We'll have charged for a Result that doesn't actually appear in
1408-
* the plan, but that's better than having a Result we don't need.
1399+
* We might not really need a Result node here. There are several ways
1400+
* that this can happen. For example, MergeAppend doesn't project, so we
1401+
* would have thought that we needed a projection to attach resjunk sort
1402+
* columns to its output ... but create_merge_append_plan might have
1403+
* added those same resjunk sort columns to both MergeAppend and its
1404+
* children. Alternatively, apply_projection_to_path might have created
1405+
* a projection path as the subpath of a Gather node even though the
1406+
* subpath was projection-capable. So, if the subpath is capable of
1407+
* projection or the desired tlist is the same expression-wise as the
1408+
* subplan's, just jam it in there. We'll have charged for a Result that
1409+
* doesn't actually appear in the plan, but that's better than having a
1410+
* Result we don't need.
14091411
*/
1410-
if (tlist_same_exprs(tlist,subplan->targetlist))
1412+
if (is_projection_capable_path(best_path->subpath)||
1413+
tlist_same_exprs(tlist,subplan->targetlist))
14111414
{
14121415
plan=subplan;
14131416
plan->targetlist=tlist;

‎src/backend/optimizer/util/pathnode.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2222,6 +2222,36 @@ apply_projection_to_path(PlannerInfo *root,
22222222
path->total_cost+=target->cost.startup-oldcost.startup+
22232223
(target->cost.per_tuple-oldcost.per_tuple)*path->rows;
22242224

2225+
/*
2226+
* If the path happens to be a Gather path, we'd like to arrange for the
2227+
* subpath to return the required target list so that workers can help
2228+
* project. But if there is something that is not parallel-safe in the
2229+
* target expressions, then we can't.
2230+
*/
2231+
if (IsA(path,GatherPath)&&
2232+
!has_parallel_hazard((Node*)target->exprs, false))
2233+
{
2234+
GatherPath*gpath= (GatherPath*)path;
2235+
2236+
/*
2237+
* We always use create_projection_path here, even if the subpath is
2238+
* projection-capable, so as to avoid modifying the subpath in place.
2239+
* It seems unlikely at present that there could be any other
2240+
* references to the subpath anyway, but better safe than sorry.
2241+
* (create_projection_plan will only insert a Result node if the
2242+
* subpath is not projection-capable, so we only include the cost of
2243+
* that node if it will actually be inserted. This is a bit grotty
2244+
* but we can improve it later if it seems important.)
2245+
*/
2246+
if (!is_projection_capable_path(gpath->subpath))
2247+
gpath->path.total_cost+=cpu_tuple_cost*gpath->subpath->rows;
2248+
gpath->subpath= (Path*)
2249+
create_projection_path(root,
2250+
gpath->subpath->parent,
2251+
gpath->subpath,
2252+
target);
2253+
}
2254+
22252255
returnpath;
22262256
}
22272257

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp