diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-07-22 19:12:02 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-07-22 19:12:02 +0000 |
commit | 37c443eefd3cac0778c915aaecdceda1a5e1d800 (patch) | |
tree | b43a0ab68dfb0af4160c3fba7f30fcc0f5a659e4 /src/backend/optimizer/util/pathnode.c | |
parent | 3758affc9b229e33f23a81053d65945183ef33e6 (diff) | |
download | postgresql-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.c | 55 |
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; } |