From 37c443eefd3cac0778c915aaecdceda1a5e1d800 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 22 Jul 2005 19:12:02 +0000 Subject: 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. --- src/backend/optimizer/util/pathnode.c | 55 ++++++++++++----------------------- 1 file changed, 18 insertions(+), 37 deletions(-) (limited to 'src/backend/optimizer/util/pathnode.c') 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; } -- cgit v1.2.3