aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/createplan.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2013-03-14 13:42:51 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2013-03-14 13:43:18 -0400
commit4387cf956b9eb13aad569634e0c4df081d76e2e3 (patch)
treec6a59e9e8010daa2b1865e06993f68599360adbe /src/backend/optimizer/plan/createplan.c
parenta5ff502fceadc7c203b0d7a11b45c73f1b421f69 (diff)
downloadpostgresql-4387cf956b9eb13aad569634e0c4df081d76e2e3.tar.gz
postgresql-4387cf956b9eb13aad569634e0c4df081d76e2e3.zip
Avoid inserting Result nodes that only compute identity projections.
The planner sometimes inserts Result nodes to perform column projections (ie, arbitrary scalar calculations) above plan nodes that lack projection logic of their own. However, we did that even if the lower plan node was in fact producing the required column set already; which is a pretty common case given the popularity of "SELECT * FROM ...". Measurements show that the useless plan node adds non-negligible overhead, especially when there are many columns in the result. So add a check to avoid inserting a Result node unless there's something useful for it to do. There are a couple of remaining places where unnecessary Result nodes could get inserted, but they are (a) much less performance-critical, and (b) coded in such a way that it's hard to avoid inserting a Result, because the desired tlist is changed on-the-fly in subsequent logic. We'll leave those alone for now. Kyotaro Horiguchi; reviewed and further hacked on by Amit Kapila and Tom Lane.
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r--src/backend/optimizer/plan/createplan.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index d668128ccb1..65a2e38fc33 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -937,10 +937,12 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path)
if (newitems || best_path->umethod == UNIQUE_PATH_SORT)
{
/*
- * If the top plan node can't do projections, we need to add a Result
- * node to help it along.
+ * If the top plan node can't do projections and its existing target
+ * list isn't already what we need, we need to add a Result node to
+ * help it along.
*/
- if (!is_projection_capable_plan(subplan))
+ if (!is_projection_capable_plan(subplan) &&
+ !tlist_same_exprs(newtlist, subplan->targetlist))
subplan = (Plan *) make_result(root, newtlist, NULL, subplan);
else
subplan->targetlist = newtlist;