@@ -6998,6 +6998,11 @@ index_other_operands_eval_cost(PlannerInfo *root, List *indexquals)
69986998 return qual_arg_cost ;
69996999}
70007000
7001+ /*
7002+ * Compute generic index access cost estimates.
7003+ *
7004+ * See struct GenericCosts in selfuncs.h for more info.
7005+ */
70017006void
70027007genericcostestimate (PlannerInfo * root ,
70037008 IndexPath * path ,
@@ -7093,16 +7098,18 @@ genericcostestimate(PlannerInfo *root,
70937098 * Estimate the number of index pages that will be retrieved.
70947099 *
70957100 * We use the simplistic method of taking a pro-rata fraction of the total
7096- * number of index pages. In effect, this counts only leaf pages and not
7097- * any overhead such as index metapage or upper tree levels.
7101+ * number of index leaf pages. We disregard any overhead such as index
7102+ * metapages or upper tree levels.
70987103 *
70997104 * In practice access to upper index levels is often nearly free because
71007105 * those tend to stay in cache under load; moreover, the cost involved is
71017106 * highly dependent on index type. We therefore ignore such costs here
71027107 * and leave it to the caller to add a suitable charge if needed.
71037108 */
7104- if (index -> pages > 1 && index -> tuples > 1 )
7105- numIndexPages = ceil (numIndexTuples * index -> pages / index -> tuples );
7109+ if (index -> pages > costs -> numNonLeafPages && index -> tuples > 1 )
7110+ numIndexPages =
7111+ ceil (numIndexTuples * (index -> pages - costs -> numNonLeafPages )
7112+ / index -> tuples );
71067113 else
71077114 numIndexPages = 1.0 ;
71087115
@@ -7693,9 +7700,18 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
76937700
76947701 /*
76957702 * Now do generic index cost estimation.
7703+ *
7704+ * While we expended effort to make realistic estimates of numIndexTuples
7705+ * and num_sa_scans, we are content to count only the btree metapage as
7706+ * non-leaf. btree fanout is typically high enough that upper pages are
7707+ * few relative to leaf pages, so accounting for them would move the
7708+ * estimates at most a percent or two. Given the uncertainty in just how
7709+ * many upper pages exist in a particular index, we'll skip trying to
7710+ * handle that.
76967711 */
76977712 costs .numIndexTuples = numIndexTuples ;
76987713 costs .num_sa_scans = num_sa_scans ;
7714+ costs .numNonLeafPages = 1 ;
76997715
77007716 genericcostestimate (root , path , loop_count , & costs );
77017717
@@ -7760,6 +7776,9 @@ hashcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
77607776{
77617777 GenericCosts costs = {0 };
77627778
7779+ /* As in btcostestimate, count only the metapage as non-leaf */
7780+ costs .numNonLeafPages = 1 ;
7781+
77637782 genericcostestimate (root , path , loop_count , & costs );
77647783
77657784 /*
@@ -7804,6 +7823,8 @@ gistcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
78047823 GenericCosts costs = {0 };
78057824 Cost descentCost ;
78067825
7826+ /* GiST has no metapage, so we treat all pages as leaf pages */
7827+
78077828 genericcostestimate (root , path , loop_count , & costs );
78087829
78097830 /*
@@ -7859,6 +7880,9 @@ spgcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
78597880 GenericCosts costs = {0 };
78607881 Cost descentCost ;
78617882
7883+ /* As in btcostestimate, count only the metapage as non-leaf */
7884+ costs .numNonLeafPages = 1 ;
7885+
78627886 genericcostestimate (root , path , loop_count , & costs );
78637887
78647888 /*
0 commit comments