aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/pathnode.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-07-22 19:12:02 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-07-22 19:12:02 +0000
commit37c443eefd3cac0778c915aaecdceda1a5e1d800 (patch)
treeb43a0ab68dfb0af4160c3fba7f30fcc0f5a659e4 /src/backend/optimizer/util/pathnode.c
parent3758affc9b229e33f23a81053d65945183ef33e6 (diff)
downloadpostgresql-37c443eefd3cac0778c915aaecdceda1a5e1d800.tar.gz
postgresql-37c443eefd3cac0778c915aaecdceda1a5e1d800.zip
Fix compare_fuzzy_path_costs() to behave a bit more sanely. The original
coding would ignore startup cost differences of less than 1% of the estimated total cost; which was OK for normal planning but highly not OK if a very small LIMIT was applied afterwards, so that startup cost becomes the name of the game. Instead, compare startup and total costs fuzzily but independently. This changes the plan selected for two queries in the regression tests; adjust expected-output files for resulting changes in row order. Per reports from Dawid Kuroczko and Sam Mason.
Diffstat (limited to 'src/backend/optimizer/util/pathnode.c')
-rw-r--r--src/backend/optimizer/util/pathnode.c55
1 files changed, 18 insertions, 37 deletions
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 4f3e8d6d9db..fc76c89329c 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.123 2005/07/15 17:09:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.124 2005/07/22 19:12:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -98,60 +98,41 @@ compare_path_costs(Path *path1, Path *path2, CostSelector criterion)
static int
compare_fuzzy_path_costs(Path *path1, Path *path2, CostSelector criterion)
{
- Cost fuzz;
-
/*
- * The fuzz factor is set at one percent of the smaller total_cost,
- * but not less than 0.01 cost units (just in case total cost is
- * zero).
+ * We use a fuzz factor of 1% of the smaller cost.
*
* XXX does this percentage need to be user-configurable?
*/
- fuzz = Min(path1->total_cost, path2->total_cost) * 0.01;
- fuzz = Max(fuzz, 0.01);
-
if (criterion == STARTUP_COST)
{
- if (Abs(path1->startup_cost - path2->startup_cost) > fuzz)
- {
- if (path1->startup_cost < path2->startup_cost)
- return -1;
- else
- return +1;
- }
+ if (path1->startup_cost > path2->startup_cost * 1.01)
+ return +1;
+ if (path2->startup_cost > path1->startup_cost * 1.01)
+ return -1;
/*
* If paths have the same startup cost (not at all unlikely),
* order them by total cost.
*/
- if (Abs(path1->total_cost - path2->total_cost) > fuzz)
- {
- if (path1->total_cost < path2->total_cost)
- return -1;
- else
- return +1;
- }
+ if (path1->total_cost > path2->total_cost * 1.01)
+ return +1;
+ if (path2->total_cost > path1->total_cost * 1.01)
+ return -1;
}
else
{
- if (Abs(path1->total_cost - path2->total_cost) > fuzz)
- {
- if (path1->total_cost < path2->total_cost)
- return -1;
- else
- return +1;
- }
+ if (path1->total_cost > path2->total_cost * 1.01)
+ return +1;
+ if (path2->total_cost > path1->total_cost * 1.01)
+ return -1;
/*
* If paths have the same total cost, order them by startup cost.
*/
- if (Abs(path1->startup_cost - path2->startup_cost) > fuzz)
- {
- if (path1->startup_cost < path2->startup_cost)
- return -1;
- else
- return +1;
- }
+ if (path1->startup_cost > path2->startup_cost * 1.01)
+ return +1;
+ if (path2->startup_cost > path1->startup_cost * 1.01)
+ return -1;
}
return 0;
}