@@ -7291,31 +7291,30 @@ gincostestimate(PG_FUNCTION_ARGS)
7291
7291
* indexStartupCost = (entryPagesFetched + dataPagesFetched ) * spc_random_page_cost ;
7292
7292
7293
7293
/*
7294
- * Now we compute the number of data pages fetched while the scan
7295
- * proceeds.
7294
+ * Now compute the number of data pages fetched during the scan.
7295
+ *
7296
+ * We assume every entry to have the same number of items, and that there
7297
+ * is no overlap between them. (XXX: tsvector and array opclasses collect
7298
+ * statistics on the frequency of individual keys; it would be nice to
7299
+ * use those here.)
7296
7300
*/
7297
-
7298
- /* data pages scanned for each exact (non-partial) matched entry */
7299
7301
dataPagesFetched = ceil (numDataPages * counts .exactEntries / numEntries );
7300
7302
7301
7303
/*
7302
- * Estimate number of data pages read, using selectivity estimation and
7303
- * capacity of data page.
7304
+ * If there is a lot of overlap among the entries, in particular if one
7305
+ * of the entries is very frequent, the above calculation can grossly
7306
+ * under-estimate. As a simple cross-check, calculate a lower bound
7307
+ * based on the overall selectivity of the quals. At a minimum, we must
7308
+ * read one item pointer for each matching entry.
7309
+ *
7310
+ * The width of each item pointer varies, based on the level of
7311
+ * compression. We don't have statistics on that, but an average of
7312
+ * around 3 bytes per item is fairly typical.
7304
7313
*/
7305
7314
dataPagesFetchedBySel = ceil (* indexSelectivity *
7306
- (numTuples / (BLCKSZ / SizeOfIptrData )));
7307
-
7315
+ (numTuples / (BLCKSZ / 3 )));
7308
7316
if (dataPagesFetchedBySel > dataPagesFetched )
7309
- {
7310
- /*
7311
- * At least one of entries is very frequent and, unfortunately, we
7312
- * couldn't get statistic about entries (only tsvector has such
7313
- * statistics). So, we obviously have too small estimation of pages
7314
- * fetched from data tree. Re-estimate it from known capacity of data
7315
- * pages
7316
- */
7317
7317
dataPagesFetched = dataPagesFetchedBySel ;
7318
- }
7319
7318
7320
7319
/* Account for cache effects, the same as above */
7321
7320
if (outer_scans > 1 || counts .arrayScans > 1 )
0 commit comments