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
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
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
|
* cost_functionscan
|
||||||
* Determines and returns the cost of scanning a function RTE.
|
* Determines and returns the cost of scanning a function RTE.
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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,
|
scan_relid,
|
||||||
best_path->parent->subplan);
|
best_path->parent->subplan);
|
||||||
|
|
||||||
|
copy_path_costsize(&scan_plan->scan.plan, best_path);
|
||||||
|
|
||||||
return scan_plan;
|
return scan_plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1503,8 +1505,14 @@ make_subqueryscan(List *qptlist,
|
|||||||
SubqueryScan *node = makeNode(SubqueryScan);
|
SubqueryScan *node = makeNode(SubqueryScan);
|
||||||
Plan *plan = &node->scan.plan;
|
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);
|
copy_plan_costsize(plan, subplan);
|
||||||
|
plan->total_cost += cpu_tuple_cost * subplan->plan_rows;
|
||||||
|
|
||||||
plan->targetlist = qptlist;
|
plan->targetlist = qptlist;
|
||||||
plan->qual = qpqual;
|
plan->qual = qpqual;
|
||||||
plan->lefttree = NULL;
|
plan->lefttree = NULL;
|
||||||
@ -1540,7 +1548,11 @@ make_append(List *appendplans, bool isTarget, List *tlist)
|
|||||||
Plan *plan = &node->plan;
|
Plan *plan = &node->plan;
|
||||||
List *subnode;
|
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->startup_cost = 0;
|
||||||
plan->total_cost = 0;
|
plan->total_cost = 0;
|
||||||
plan->plan_rows = 0;
|
plan->plan_rows = 0;
|
||||||
@ -1556,6 +1568,7 @@ make_append(List *appendplans, bool isTarget, List *tlist)
|
|||||||
if (plan->plan_width < subplan->plan_width)
|
if (plan->plan_width < subplan->plan_width)
|
||||||
plan->plan_width = subplan->plan_width;
|
plan->plan_width = subplan->plan_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
plan->targetlist = tlist;
|
plan->targetlist = tlist;
|
||||||
plan->qual = NIL;
|
plan->qual = NIL;
|
||||||
plan->lefttree = NULL;
|
plan->lefttree = NULL;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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->parent = rel;
|
||||||
pathnode->pathkeys = pathkeys;
|
pathnode->pathkeys = pathkeys;
|
||||||
|
|
||||||
/* just copy the subplan's cost estimates */
|
cost_subqueryscan(pathnode, rel);
|
||||||
pathnode->startup_cost = rel->subplan->startup_cost;
|
|
||||||
pathnode->total_cost = rel->subplan->total_cost;
|
|
||||||
|
|
||||||
return pathnode;
|
return pathnode;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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);
|
List *indexQuals, bool is_injoin);
|
||||||
extern void cost_tidscan(Path *path, Query *root,
|
extern void cost_tidscan(Path *path, Query *root,
|
||||||
RelOptInfo *baserel, List *tideval);
|
RelOptInfo *baserel, List *tideval);
|
||||||
|
extern void cost_subqueryscan(Path *path, RelOptInfo *baserel);
|
||||||
extern void cost_functionscan(Path *path, Query *root,
|
extern void cost_functionscan(Path *path, Query *root,
|
||||||
RelOptInfo *baserel);
|
RelOptInfo *baserel);
|
||||||
extern void cost_sort(Path *path, Query *root,
|
extern void cost_sort(Path *path, Query *root,
|
||||||
|
Loading…
Reference in New Issue
Block a user