]> granicus.if.org Git - postgresql/commitdiff
Add a fudge factor to genericcostestimate() to prevent the planner from
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 24 Jul 2006 01:19:48 +0000 (01:19 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 24 Jul 2006 01:19:48 +0000 (01:19 +0000)
thinking that indexes of different sizes are equally attractive.  Per
gripe from Jim Nasby.  (I remain unconvinced that there's such a problem
in existing releases, but CVS HEAD definitely has got a problem because
of its new count-only-leaf-pages approach to indexscan costing.)

src/backend/utils/adt/selfuncs.c

index 6e08518bc9b4eedb27d2e3ae3a5354fbfbe7aa9d..2a70b6273574fbeb0c05736ced58ec07fd3754e0 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.209 2006/07/14 14:52:24 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.210 2006/07/24 01:19:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4657,6 +4657,24 @@ genericcostestimate(PlannerInfo *root,
                *indexTotalCost = numIndexPages * random_page_cost;
        }
 
+       /*
+        * A difficulty with the leaf-pages-only cost approach is that for
+        * small selectivities (eg, single index tuple fetched) all indexes
+        * will look equally attractive because we will estimate exactly 1
+        * leaf page to be fetched.  All else being equal, we should prefer
+        * physically smaller indexes over larger ones.  (An index might be
+        * smaller because it is partial or because it contains fewer columns;
+        * presumably the other columns in the larger index aren't useful to
+        * the query, or the larger index would have better selectivity.)
+        *
+        * We can deal with this by adding a very small "fudge factor" that
+        * depends on the index size.  The fudge factor used here is one
+        * random_page_cost per 100000 index pages, which should be small
+        * enough to not alter index-vs-seqscan decisions, but will prevent
+        * indexes of different sizes from looking exactly equally attractive.
+        */
+       *indexTotalCost += index->pages * random_page_cost / 100000.0;
+
        /*
         * CPU cost: any complex expressions in the indexquals will need to be
         * evaluated once at the start of the scan to reduce them to runtime keys