Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7985398

Browse files
committed
Clamp indexscan filter condition cost estimate to be not less than zero.
cost_index tries to estimate the per-tuple costs of evaluating filterconditions (a/k/a qpquals) by subtracting the estimated cost of theindexqual conditions from that of the baserestrictinfo conditions. This iscorrect so long as the indexquals list is a subset of the baserestrictinfolist. However, in the presence of derived indexable conditions it'scompletely wrong, leading to bogus or even negative scan cost estimates,as seen for example in bug #6579 from Istvan Endredy. In practice theproblem isn't severe except in the specific case of a LIKE optimization ona functional index containing a very expensive function.A proper fix for this might change cost estimates by more than people wouldlike for stable branches, so in the back branches let's just clamp the costdifference to be not less than zero. That will at least prevent completelyinsane behavior, while not changing the results normally.
1 parent35400e1 commit7985398

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

‎src/backend/optimizer/path/costsize.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,14 @@ cost_index(IndexPath *path, PlannerInfo *root,
392392
* some of the indexquals are join clauses and shouldn't be subtracted.
393393
* Rather than work out exactly how much to subtract, we don't subtract
394394
* anything.
395+
*
396+
* XXX actually, this calculation is almost completely bogus, because
397+
* indexquals will contain derived indexable conditions which might be
398+
* quite different from the "original" quals in baserestrictinfo. We
399+
* ought to determine the actual qpqual list and cost that, rather than
400+
* using this shortcut. But that's too invasive a change to consider
401+
* back-patching, so for the moment we just mask the worst aspects of the
402+
* problem by clamping the subtracted amount.
395403
*/
396404
startup_cost+=baserel->baserestrictcost.startup;
397405
cpu_per_tuple=cpu_tuple_cost+baserel->baserestrictcost.per_tuple;
@@ -402,7 +410,8 @@ cost_index(IndexPath *path, PlannerInfo *root,
402410

403411
cost_qual_eval(&index_qual_cost,indexQuals,root);
404412
/* any startup cost still has to be paid ... */
405-
cpu_per_tuple-=index_qual_cost.per_tuple;
413+
cpu_per_tuple-=Min(index_qual_cost.per_tuple,
414+
baserel->baserestrictcost.per_tuple);
406415
}
407416

408417
run_cost+=cpu_per_tuple*tuples_fetched;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp