Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit de816a0

Browse files
committed
Repair misestimation of indexscan CPU costs. When an indexqual contains
a run-time key (that is, a nonconstant expression compared to the index variable), the key is evaluated just once per scan, but we were charging costs as though it were evaluated once per visited index entry.
1 parent 0966516 commit de816a0

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

src/backend/utils/adt/selfuncs.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.154 2004/01/07 18:56:28 neilc Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.155 2004/01/17 20:09:35 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -3897,6 +3897,8 @@ genericcostestimate(Query *root, RelOptInfo *rel,
38973897
double numIndexTuples;
38983898
double numIndexPages;
38993899
QualCost index_qual_cost;
3900+
double qual_op_cost;
3901+
double qual_arg_cost;
39003902
List *selectivityQuals;
39013903

39023904
/*
@@ -3976,16 +3978,31 @@ genericcostestimate(Query *root, RelOptInfo *rel,
39763978
/*
39773979
* Compute the index access cost.
39783980
*
3979-
* Our generic assumption is that the index pages will be read
3980-
* sequentially, so they have cost 1.0 each, not random_page_cost.
3981-
* Also, we charge for evaluation of the indexquals at each index
3982-
* tuple. All the costs are assumed to be paid incrementally during
3983-
* the scan.
3981+
* Disk cost: our generic assumption is that the index pages will be
3982+
* read sequentially, so they have cost 1.0 each, not random_page_cost.
3983+
*/
3984+
*indexTotalCost = numIndexPages;
3985+
3986+
/*
3987+
* CPU cost: any complex expressions in the indexquals will need to
3988+
* be evaluated once at the start of the scan to reduce them to runtime
3989+
* keys to pass to the index AM (see nodeIndexscan.c). We model the
3990+
* per-tuple CPU costs as cpu_index_tuple_cost plus one cpu_operator_cost
3991+
* per indexqual operator.
3992+
*
3993+
* Note: this neglects the possible costs of rechecking lossy operators
3994+
* and OR-clause expressions. Detecting that that might be needed seems
3995+
* more expensive than it's worth, though, considering all the other
3996+
* inaccuracies here ...
39843997
*/
39853998
cost_qual_eval(&index_qual_cost, indexQuals);
3986-
*indexStartupCost = index_qual_cost.startup;
3987-
*indexTotalCost = numIndexPages +
3988-
(cpu_index_tuple_cost + index_qual_cost.per_tuple) * numIndexTuples;
3999+
qual_op_cost = cpu_operator_cost * length(indexQuals);
4000+
qual_arg_cost = index_qual_cost.startup +
4001+
index_qual_cost.per_tuple - qual_op_cost;
4002+
if (qual_arg_cost < 0) /* just in case... */
4003+
qual_arg_cost = 0;
4004+
*indexStartupCost = qual_arg_cost;
4005+
*indexTotalCost += numIndexTuples * (cpu_index_tuple_cost + qual_op_cost);
39894006

39904007
/*
39914008
* Generic assumption about index correlation: there isn't any.

0 commit comments

Comments
 (0)