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

Commit9d6af73

Browse files
committed
Use fuzzy path cost tiebreaking rule in our oldest supported branches.
We've been doing it that way since 9.2, cf commit33e9915,but some recently-added regression test cases are making a few buildfarmmembers fail (ie choose the "wrong" plan) in 9.0 and 9.1 due toplatform-specific roundoff differences in cost calculations. To fix,back-port the patch that made add_path treat cost difference ratios ofless than 1e-10 as equal.
1 parent24906bb commit9d6af73

File tree

1 file changed

+29
-21
lines changed

1 file changed

+29
-21
lines changed

‎src/backend/optimizer/util/pathnode.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,44 +92,45 @@ compare_path_costs(Path *path1, Path *path2, CostSelector criterion)
9292
* same if they agree to within a "fuzz factor". This is used by add_path
9393
* to avoid keeping both of a pair of paths that really have insignificantly
9494
* different cost.
95+
*
96+
* The fuzz_factor argument must be 1.0 plus delta, where delta is the
97+
* fraction of the smaller cost that is considered to be a significant
98+
* difference. For example, fuzz_factor = 1.01 makes the fuzziness limit
99+
* be 1% of the smaller cost.
95100
*/
96101
staticint
97-
compare_fuzzy_path_costs(Path*path1,Path*path2,CostSelectorcriterion)
102+
compare_fuzzy_path_costs(Path*path1,Path*path2,CostSelectorcriterion,
103+
doublefuzz_factor)
98104
{
99-
/*
100-
* We use a fuzz factor of 1% of the smaller cost.
101-
*
102-
* XXX does this percentage need to be user-configurable?
103-
*/
104105
if (criterion==STARTUP_COST)
105106
{
106-
if (path1->startup_cost>path2->startup_cost*1.01)
107+
if (path1->startup_cost>path2->startup_cost*fuzz_factor)
107108
return+1;
108-
if (path2->startup_cost>path1->startup_cost*1.01)
109+
if (path2->startup_cost>path1->startup_cost*fuzz_factor)
109110
return-1;
110111

111112
/*
112113
* If paths have the same startup cost (not at all unlikely), order
113114
* them by total cost.
114115
*/
115-
if (path1->total_cost>path2->total_cost*1.01)
116+
if (path1->total_cost>path2->total_cost*fuzz_factor)
116117
return+1;
117-
if (path2->total_cost>path1->total_cost*1.01)
118+
if (path2->total_cost>path1->total_cost*fuzz_factor)
118119
return-1;
119120
}
120121
else
121122
{
122-
if (path1->total_cost>path2->total_cost*1.01)
123+
if (path1->total_cost>path2->total_cost*fuzz_factor)
123124
return+1;
124-
if (path2->total_cost>path1->total_cost*1.01)
125+
if (path2->total_cost>path1->total_cost*fuzz_factor)
125126
return-1;
126127

127128
/*
128129
* If paths have the same total cost, order them by startup cost.
129130
*/
130-
if (path1->startup_cost>path2->startup_cost*1.01)
131+
if (path1->startup_cost>path2->startup_cost*fuzz_factor)
131132
return+1;
132-
if (path2->startup_cost>path1->startup_cost*1.01)
133+
if (path2->startup_cost>path1->startup_cost*fuzz_factor)
133134
return-1;
134135
}
135136
return0;
@@ -277,9 +278,11 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
277278
/*
278279
* As of Postgres 8.0, we use fuzzy cost comparison to avoid wasting
279280
* cycles keeping paths that are really not significantly different in
280-
* cost.
281+
* cost. We use a 1% fuzziness limit. (XXX does this percentage need
282+
* to be user-configurable?)
281283
*/
282-
costcmp=compare_fuzzy_path_costs(new_path,old_path,TOTAL_COST);
284+
costcmp=compare_fuzzy_path_costs(new_path,old_path,
285+
TOTAL_COST,1.01);
283286

284287
/*
285288
* If the two paths compare differently for startup and total cost,
@@ -292,7 +295,7 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
292295
*/
293296
if (costcmp==0||
294297
costcmp==compare_fuzzy_path_costs(new_path,old_path,
295-
STARTUP_COST))
298+
STARTUP_COST,1.01))
296299
{
297300
switch (compare_pathkeys(new_path->pathkeys,old_path->pathkeys))
298301
{
@@ -305,11 +308,16 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
305308
{
306309
/*
307310
* Same pathkeys, and fuzzily the same cost, so keep
308-
* just one --- but we'll do an exact cost comparison
309-
* to decide which.
311+
* just one; to decide which, do a fuzzy total-cost
312+
* comparison with very small fuzz limit. (We used to
313+
* do an exact cost comparison, but that results in
314+
* annoying platform-specific plan variations due to
315+
* roundoff in the cost estimates.) If things are
316+
* still tied, arbitrarily keep only the old path.
310317
*/
311-
if (compare_path_costs(new_path,old_path,
312-
TOTAL_COST)<0)
318+
if (compare_fuzzy_path_costs(new_path,old_path,
319+
TOTAL_COST,
320+
1.0000000001)<0)
313321
remove_old= true;/* new dominates old */
314322
else
315323
accept_new= false;/* old equals or dominates new */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp