1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-08 11:42:09 +03:00

Avoid projecting tuples unnecessarily in Gather and Gather Merge.

It's most often the case that the target list for the Gather (Merge)
node matches the target list supplied by the underlying plan node;
when this is so, we can avoid the overhead of projecting.

This depends on commit f455e1125e for
proper functioning.

Idea by Andres Freund.  Patch by me.  Review by Amit Kapila.

Discussion: http://postgr.es/m/CA+TgmoZ0ZL=cesZFq8c9NnfK6bqy-wwUd3_74iYGodYrSoQ7Fw@mail.gmail.com
This commit is contained in:
Robert Haas
2017-11-25 10:49:17 -05:00
parent 0f2458ff5f
commit b10967eddf
5 changed files with 110 additions and 87 deletions

View File

@ -115,11 +115,20 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags)
outerNode = outerPlan(node);
outerPlanState(gm_state) = ExecInitNode(outerNode, estate, eflags);
/*
* Store the tuple descriptor into gather merge state, so we can use it
* while initializing the gather merge slots.
*/
if (!ExecContextForcesOids(outerPlanState(gm_state), &hasoid))
hasoid = false;
tupDesc = ExecTypeFromTL(outerNode->targetlist, hasoid);
gm_state->tupDesc = tupDesc;
/*
* Initialize result tuple type and projection info.
*/
ExecAssignResultTypeFromTL(&gm_state->ps);
ExecAssignProjectionInfo(&gm_state->ps, NULL);
ExecConditionalAssignProjectionInfo(&gm_state->ps, tupDesc, OUTER_VAR);
/*
* initialize sort-key information
@ -151,15 +160,6 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags)
}
}
/*
* Store the tuple descriptor into gather merge state, so we can use it
* while initializing the gather merge slots.
*/
if (!ExecContextForcesOids(outerPlanState(gm_state), &hasoid))
hasoid = false;
tupDesc = ExecTypeFromTL(outerNode->targetlist, hasoid);
gm_state->tupDesc = tupDesc;
/* Now allocate the workspace for gather merge */
gather_merge_setup(gm_state);
@ -257,6 +257,10 @@ ExecGatherMerge(PlanState *pstate)
if (TupIsNull(slot))
return NULL;
/* If no projection is required, we're done. */
if (node->ps.ps_ProjInfo == NULL)
return slot;
/*
* Form the result tuple using ExecProject(), and return it.
*/