aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-07-14 22:35:54 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-07-14 22:35:54 +0000
commit3d09f6c5609da36270c77b24f87313eac94a7635 (patch)
tree7405aa50f97c4e0ab57c98bfe98e5755c771f029 /src
parentb800196230c7eca35d781df39cf3a4b739c86300 (diff)
downloadpostgresql-3d09f6c5609da36270c77b24f87313eac94a7635.tar.gz
postgresql-3d09f6c5609da36270c77b24f87313eac94a7635.zip
Make cost estimates for SubqueryScan more realistic: charge cpu_tuple_cost
for each row processed, and don't forget the evaluation cost of any restriction clauses attached to the node. Per discussion with Greg Stark.
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/path/costsize.c34
-rw-r--r--src/backend/optimizer/plan/createplan.c19
-rw-r--r--src/backend/optimizer/util/pathnode.c6
-rw-r--r--src/include/optimizer/cost.h3
4 files changed, 53 insertions, 9 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 34a3aaf1c94..3011f687c59 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -49,7 +49,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.109 2003/06/29 23:05:04 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.110 2003/07/14 22:35:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -416,6 +416,38 @@ cost_tidscan(Path *path, Query *root,
}
/*
+ * cost_subqueryscan
+ * Determines and returns the cost of scanning a subquery RTE.
+ */
+void
+cost_subqueryscan(Path *path, RelOptInfo *baserel)
+{
+ Cost startup_cost;
+ Cost run_cost;
+ Cost cpu_per_tuple;
+
+ /* Should only be applied to base relations that are subqueries */
+ Assert(baserel->relid > 0);
+ Assert(baserel->rtekind == RTE_SUBQUERY);
+
+ /*
+ * Cost of path is cost of evaluating the subplan, plus cost of
+ * evaluating any restriction clauses that will be attached to the
+ * SubqueryScan node, plus cpu_tuple_cost to account for selection
+ * and projection overhead.
+ */
+ path->startup_cost = baserel->subplan->startup_cost;
+ path->total_cost = baserel->subplan->total_cost;
+
+ startup_cost = baserel->baserestrictcost.startup;
+ cpu_per_tuple = cpu_tuple_cost + baserel->baserestrictcost.per_tuple;
+ run_cost = cpu_per_tuple * baserel->tuples;
+
+ path->startup_cost += startup_cost;
+ path->total_cost += startup_cost + run_cost;
+}
+
+/*
* cost_functionscan
* Determines and returns the cost of scanning a function RTE.
*/
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 1cdc3628b20..79855b00c0f 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.147 2003/06/29 23:05:04 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.148 2003/07/14 22:35:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -811,6 +811,8 @@ create_subqueryscan_plan(Path *best_path, List *tlist, List *scan_clauses)
scan_relid,
best_path->parent->subplan);
+ copy_path_costsize(&scan_plan->scan.plan, best_path);
+
return scan_plan;
}
@@ -1503,8 +1505,14 @@ make_subqueryscan(List *qptlist,
SubqueryScan *node = makeNode(SubqueryScan);
Plan *plan = &node->scan.plan;
- /* cost is figured here for the convenience of prepunion.c */
+ /*
+ * Cost is figured here for the convenience of prepunion.c. Note this
+ * is only correct for the case where qpqual is empty; otherwise caller
+ * should overwrite cost with a better estimate.
+ */
copy_plan_costsize(plan, subplan);
+ plan->total_cost += cpu_tuple_cost * subplan->plan_rows;
+
plan->targetlist = qptlist;
plan->qual = qpqual;
plan->lefttree = NULL;
@@ -1540,7 +1548,11 @@ make_append(List *appendplans, bool isTarget, List *tlist)
Plan *plan = &node->plan;
List *subnode;
- /* compute costs from subplan costs */
+ /*
+ * Compute cost as sum of subplan costs. We charge nothing extra for
+ * the Append itself, which perhaps is too optimistic, but since it
+ * doesn't do any selection or projection, it is a pretty cheap node.
+ */
plan->startup_cost = 0;
plan->total_cost = 0;
plan->plan_rows = 0;
@@ -1556,6 +1568,7 @@ make_append(List *appendplans, bool isTarget, List *tlist)
if (plan->plan_width < subplan->plan_width)
plan->plan_width = subplan->plan_width;
}
+
plan->targetlist = tlist;
plan->qual = NIL;
plan->lefttree = NULL;
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 9e919079ccf..19198bf2494 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.91 2003/06/29 23:05:04 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.92 2003/07/14 22:35:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -686,9 +686,7 @@ create_subqueryscan_path(RelOptInfo *rel, List *pathkeys)
pathnode->parent = rel;
pathnode->pathkeys = pathkeys;
- /* just copy the subplan's cost estimates */
- pathnode->startup_cost = rel->subplan->startup_cost;
- pathnode->total_cost = rel->subplan->total_cost;
+ cost_subqueryscan(pathnode, rel);
return pathnode;
}
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index 45c83191a26..ad2122f46e7 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: cost.h,v 1.53 2003/06/11 15:01:15 momjian Exp $
+ * $Id: cost.h,v 1.54 2003/07/14 22:35:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -56,6 +56,7 @@ extern void cost_index(Path *path, Query *root,
List *indexQuals, bool is_injoin);
extern void cost_tidscan(Path *path, Query *root,
RelOptInfo *baserel, List *tideval);
+extern void cost_subqueryscan(Path *path, RelOptInfo *baserel);
extern void cost_functionscan(Path *path, Query *root,
RelOptInfo *baserel);
extern void cost_sort(Path *path, Query *root,