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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy