mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
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.
This commit is contained in:
parent
b800196230
commit
3d09f6c560
@ -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 $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -415,6 +415,38 @@ cost_tidscan(Path *path, Query *root,
|
||||
path->total_cost = startup_cost + run_cost;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user