Commit d4ce5a4f authored by Tom Lane's avatar Tom Lane

Revise cost_qual_eval() to compute both startup (one-time) and per-tuple

costs for expression evaluation, not only per-tuple cost as before.
This extension is needed in order to deal realistically with hashed or
materialized sub-selects.
parent d51260aa
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/indexcost.sgml,v 2.12 2002/08/22 00:01:40 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/indexcost.sgml,v 2.13 2003/01/12 22:35:29 tgl Exp $
--> -->
<chapter id="indexcost"> <chapter id="indexcost">
...@@ -237,9 +237,10 @@ amcostestimate (Query *root, ...@@ -237,9 +237,10 @@ amcostestimate (Query *root,
* Also, we charge for evaluation of the indexquals at each index tuple. * Also, we charge for evaluation of the indexquals at each index tuple.
* All the costs are assumed to be paid incrementally during the scan. * All the costs are assumed to be paid incrementally during the scan.
*/ */
*indexStartupCost = 0; cost_qual_eval(&index_qual_cost, indexQuals);
*indexStartupCost = index_qual_cost.startup;
*indexTotalCost = numIndexPages + *indexTotalCost = numIndexPages +
(cpu_index_tuple_cost + cost_qual_eval(indexQuals)) * numIndexTuples; (cpu_index_tuple_cost + index_qual_cost.per_tuple) * numIndexTuples;
</programlisting> </programlisting>
</para> </para>
</step> </step>
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.79 2002/12/17 01:18:25 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.80 2003/01/12 22:35:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -396,7 +396,7 @@ distribute_qual_to_rels(Query *root, Node *clause, ...@@ -396,7 +396,7 @@ distribute_qual_to_rels(Query *root, Node *clause,
restrictinfo->clause = (Expr *) clause; restrictinfo->clause = (Expr *) clause;
restrictinfo->subclauseindices = NIL; restrictinfo->subclauseindices = NIL;
restrictinfo->eval_cost = -1; /* not computed until needed */ restrictinfo->eval_cost.startup = -1; /* not computed until needed */
restrictinfo->this_selec = -1; /* not computed until needed */ restrictinfo->this_selec = -1; /* not computed until needed */
restrictinfo->mergejoinoperator = InvalidOid; restrictinfo->mergejoinoperator = InvalidOid;
restrictinfo->left_sortop = InvalidOid; restrictinfo->left_sortop = InvalidOid;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.84 2003/01/05 00:56:40 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.85 2003/01/12 22:35:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -853,7 +853,7 @@ adjust_inherited_attrs_mutator(Node *node, ...@@ -853,7 +853,7 @@ adjust_inherited_attrs_mutator(Node *node,
adjust_inherited_attrs_mutator((Node *) oldinfo->clause, context); adjust_inherited_attrs_mutator((Node *) oldinfo->clause, context);
newinfo->subclauseindices = NIL; newinfo->subclauseindices = NIL;
newinfo->eval_cost = -1; /* reset these too */ newinfo->eval_cost.startup = -1; /* reset these too */
newinfo->this_selec = -1; newinfo->this_selec = -1;
newinfo->left_pathkey = NIL; /* and these */ newinfo->left_pathkey = NIL; /* and these */
newinfo->right_pathkey = NIL; newinfo->right_pathkey = NIL;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.41 2002/11/24 21:52:14 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/relnode.c,v 1.42 2003/01/12 22:35:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -149,7 +149,8 @@ make_base_rel(Query *root, int relid) ...@@ -149,7 +149,8 @@ make_base_rel(Query *root, int relid)
rel->joinrti = 0; rel->joinrti = 0;
rel->joinrteids = NIL; rel->joinrteids = NIL;
rel->baserestrictinfo = NIL; rel->baserestrictinfo = NIL;
rel->baserestrictcost = 0; rel->baserestrictcost.startup = 0;
rel->baserestrictcost.per_tuple = 0;
rel->outerjoinset = NIL; rel->outerjoinset = NIL;
rel->joininfo = NIL; rel->joininfo = NIL;
rel->index_outer_relids = NIL; rel->index_outer_relids = NIL;
...@@ -363,7 +364,8 @@ build_join_rel(Query *root, ...@@ -363,7 +364,8 @@ build_join_rel(Query *root,
joinrel->joinrteids = nconc(listCopy(outer_rel->joinrteids), joinrel->joinrteids = nconc(listCopy(outer_rel->joinrteids),
inner_rel->joinrteids); inner_rel->joinrteids);
joinrel->baserestrictinfo = NIL; joinrel->baserestrictinfo = NIL;
joinrel->baserestrictcost = 0; joinrel->baserestrictcost.startup = 0;
joinrel->baserestrictcost.per_tuple = 0;
joinrel->outerjoinset = NIL; joinrel->outerjoinset = NIL;
joinrel->joininfo = NIL; joinrel->joininfo = NIL;
joinrel->index_outer_relids = NIL; joinrel->index_outer_relids = NIL;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.124 2002/12/17 01:18:35 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.125 2003/01/12 22:35:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -3757,6 +3757,7 @@ genericcostestimate(Query *root, RelOptInfo *rel, ...@@ -3757,6 +3757,7 @@ genericcostestimate(Query *root, RelOptInfo *rel,
{ {
double numIndexTuples; double numIndexTuples;
double numIndexPages; double numIndexPages;
QualCost index_qual_cost;
List *selectivityQuals = indexQuals; List *selectivityQuals = indexQuals;
/* /*
...@@ -3826,9 +3827,10 @@ genericcostestimate(Query *root, RelOptInfo *rel, ...@@ -3826,9 +3827,10 @@ genericcostestimate(Query *root, RelOptInfo *rel,
* tuple. All the costs are assumed to be paid incrementally during * tuple. All the costs are assumed to be paid incrementally during
* the scan. * the scan.
*/ */
*indexStartupCost = 0; cost_qual_eval(&index_qual_cost, indexQuals);
*indexStartupCost = index_qual_cost.startup;
*indexTotalCost = numIndexPages + *indexTotalCost = numIndexPages +
(cpu_index_tuple_cost + cost_qual_eval(indexQuals)) * numIndexTuples; (cpu_index_tuple_cost + index_qual_cost.per_tuple) * numIndexTuples;
/* /*
* Generic assumption about index correlation: there isn't any. * Generic assumption about index correlation: there isn't any.
......
...@@ -7,7 +7,7 @@ ...@@ -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: relation.h,v 1.74 2002/12/12 15:49:40 tgl Exp $ * $Id: relation.h,v 1.75 2003/01/12 22:35:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -35,6 +35,16 @@ typedef enum CostSelector ...@@ -35,6 +35,16 @@ typedef enum CostSelector
STARTUP_COST, TOTAL_COST STARTUP_COST, TOTAL_COST
} CostSelector; } CostSelector;
/*
* The cost estimate produced by cost_qual_eval() includes both a one-time
* (startup) cost, and a per-tuple cost.
*/
typedef struct QualCost
{
Cost startup; /* one-time cost */
Cost per_tuple; /* per-evaluation cost */
} QualCost;
/*---------- /*----------
* RelOptInfo * RelOptInfo
* Per-relation information for planning/optimization * Per-relation information for planning/optimization
...@@ -199,7 +209,7 @@ typedef struct RelOptInfo ...@@ -199,7 +209,7 @@ typedef struct RelOptInfo
/* used by various scans and joins: */ /* used by various scans and joins: */
List *baserestrictinfo; /* RestrictInfo structures (if List *baserestrictinfo; /* RestrictInfo structures (if
* base rel) */ * base rel) */
Cost baserestrictcost; /* cost of evaluating the above */ QualCost baserestrictcost; /* cost of evaluating the above */
Relids outerjoinset; /* integer list of base relids */ Relids outerjoinset; /* integer list of base relids */
List *joininfo; /* JoinInfo structures */ List *joininfo; /* JoinInfo structures */
...@@ -570,7 +580,7 @@ typedef struct RestrictInfo ...@@ -570,7 +580,7 @@ typedef struct RestrictInfo
/* subclauseindices is a List of Lists of IndexOptInfos */ /* subclauseindices is a List of Lists of IndexOptInfos */
/* cache space for costs (currently only used for join clauses) */ /* cache space for costs (currently only used for join clauses) */
Cost eval_cost; /* eval cost of clause; -1 if not yet set */ QualCost eval_cost; /* eval cost of clause; -1 if not yet set */
Selectivity this_selec; /* selectivity; -1 if not yet set */ Selectivity this_selec; /* selectivity; -1 if not yet set */
/* valid if clause is mergejoinable, else InvalidOid: */ /* valid if clause is mergejoinable, else InvalidOid: */
......
...@@ -7,7 +7,7 @@ ...@@ -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.49 2002/11/30 05:21:03 tgl Exp $ * $Id: cost.h,v 1.50 2003/01/12 22:35:29 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -83,7 +83,7 @@ extern void cost_hashjoin(Path *path, Query *root, ...@@ -83,7 +83,7 @@ extern void cost_hashjoin(Path *path, Query *root,
Path *outer_path, Path *inner_path, Path *outer_path, Path *inner_path,
List *restrictlist, List *restrictlist,
List *hashclauses); List *hashclauses);
extern Cost cost_qual_eval(List *quals); extern void cost_qual_eval(QualCost *cost, List *quals);
extern void set_baserel_size_estimates(Query *root, RelOptInfo *rel); extern void set_baserel_size_estimates(Query *root, RelOptInfo *rel);
extern void set_joinrel_size_estimates(Query *root, RelOptInfo *rel, extern void set_joinrel_size_estimates(Query *root, RelOptInfo *rel,
RelOptInfo *outer_rel, RelOptInfo *outer_rel,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment