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

Commit8d9a28e

Browse files
committed
Use fuzzy comparison of path costs in add_path(), so that paths with the
same path keys and nearly equivalent costs will be considered redundant.The exact nature of the fuzziness may get adjusted later based on currentdiscussions, but no one has shot a hole in the basic idea yet ...
1 parent047a2ce commit8d9a28e

File tree

1 file changed

+96
-8
lines changed

1 file changed

+96
-8
lines changed

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

Lines changed: 96 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.102 2004/03/02 16:42:20 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.103 2004/03/29 19:58:04 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -84,6 +84,76 @@ compare_path_costs(Path *path1, Path *path2, CostSelector criterion)
8484
return0;
8585
}
8686

87+
/*
88+
* compare_fuzzy_path_costs
89+
* Return -1, 0, or +1 according as path1 is cheaper, the same cost,
90+
* or more expensive than path2 for the specified criterion.
91+
*
92+
* This differs from compare_path_costs in that we consider the costs the
93+
* same if they agree to within a "fuzz factor". This is used by add_path
94+
* to avoid keeping both of a pair of paths that really have insignificantly
95+
* different cost.
96+
*/
97+
staticint
98+
compare_fuzzy_path_costs(Path*path1,Path*path2,CostSelectorcriterion)
99+
{
100+
Costfuzz;
101+
102+
/*
103+
* The fuzz factor is set at one percent of the smaller total_cost, but
104+
* not less than 0.01 cost units (just in case total cost is zero).
105+
*
106+
* XXX does this percentage need to be user-configurable?
107+
*/
108+
fuzz=Min(path1->total_cost,path2->total_cost)*0.01;
109+
fuzz=Max(fuzz,0.01);
110+
111+
if (criterion==STARTUP_COST)
112+
{
113+
if (Abs(path1->startup_cost-path2->startup_cost)>fuzz)
114+
{
115+
if (path1->startup_cost<path2->startup_cost)
116+
return-1;
117+
else
118+
return+1;
119+
}
120+
121+
/*
122+
* If paths have the same startup cost (not at all unlikely),
123+
* order them by total cost.
124+
*/
125+
if (Abs(path1->total_cost-path2->total_cost)>fuzz)
126+
{
127+
if (path1->total_cost<path2->total_cost)
128+
return-1;
129+
else
130+
return+1;
131+
}
132+
}
133+
else
134+
{
135+
if (Abs(path1->total_cost-path2->total_cost)>fuzz)
136+
{
137+
if (path1->total_cost<path2->total_cost)
138+
return-1;
139+
else
140+
return+1;
141+
}
142+
143+
/*
144+
* If paths have the same total cost, order them by startup cost.
145+
*/
146+
if (Abs(path1->startup_cost-path2->startup_cost)>fuzz)
147+
{
148+
if (path1->startup_cost<path2->startup_cost)
149+
return-1;
150+
else
151+
return+1;
152+
}
153+
}
154+
return0;
155+
}
156+
87157
/*
88158
* compare_path_fractional_costs
89159
* Return -1, 0, or +1 according as path1 is cheaper, the same cost,
@@ -215,29 +285,47 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
215285
boolremove_old= false;/* unless new proves superior */
216286
intcostcmp;
217287

218-
costcmp=compare_path_costs(new_path,old_path,TOTAL_COST);
288+
/*
289+
* As of Postgres 7.5, we use fuzzy cost comparison to avoid wasting
290+
* cycles keeping paths that are really not significantly different
291+
* in cost.
292+
*/
293+
costcmp=compare_fuzzy_path_costs(new_path,old_path,TOTAL_COST);
219294

220295
/*
221296
* If the two paths compare differently for startup and total
222297
* cost, then we want to keep both, and we can skip the (much
223298
* slower) comparison of pathkeys.If they compare the same,
224299
* proceed with the pathkeys comparison. Note: this test relies
225-
* on the fact thatcompare_path_costs will only return 0 if both
226-
* costs are equal (and, therefore, there's no need to call it
227-
* twice in that case).
300+
* on the fact thatcompare_fuzzy_path_costs will only return 0 if
301+
*bothcosts areeffectivelyequal (and, therefore, there's no need
302+
*to call ittwice in that case).
228303
*/
229304
if (costcmp==0||
230-
costcmp==compare_path_costs(new_path,old_path,
231-
STARTUP_COST))
305+
costcmp==compare_fuzzy_path_costs(new_path,old_path,
306+
STARTUP_COST))
232307
{
233308
switch (compare_pathkeys(new_path->pathkeys,old_path->pathkeys))
234309
{
235310
casePATHKEYS_EQUAL:
236311
if (costcmp<0)
237312
remove_old= true;/* new dominates old */
313+
elseif (costcmp>0)
314+
accept_new= false;/* old dominates new */
238315
else
239-
accept_new= false;/* old equals or dominates
316+
{
317+
/*
318+
* Same pathkeys, and fuzzily the same cost, so
319+
* keep just one --- but we'll do an exact cost
320+
* comparison to decide which.
321+
*/
322+
if (compare_path_costs(new_path,old_path,
323+
TOTAL_COST)<0)
324+
remove_old= true;/* new dominates old */
325+
else
326+
accept_new= false;/* old equals or dominates
240327
* new */
328+
}
241329
break;
242330
casePATHKEYS_BETTER1:
243331
if (costcmp <=0)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp