From f760433da4826ad3f33148b812a2bb7dad3b4580 Mon Sep 17 00:00:00 2001 From: ejrh Date: Tue, 27 Nov 2018 20:31:58 +1300 Subject: [PATCH 4/4] TID selectivity: reduce the density of the last page by half This takes into account the fact that the last page will have only half the density, on average, as other pages in a table. --- src/backend/utils/adt/selfuncs.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index eca20c1..2202a98 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -580,8 +580,16 @@ scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq, * naively assume there will never be any dead tuples or empty * space at the start or in the middle of the page. This is * likely fine for the purposes here. + * + * Since the last page will, on average, be only half full, we + * can estimate it to have half as many tuples as earlier pages. + * So give it half the weight of a regular page. */ - density = vardata->rel->tuples / vardata->rel->pages; + density = vardata->rel->tuples / (vardata->rel->pages - 0.5); + + /* If it's the last page, it has half the density. */ + if (block >= vardata->rel->pages - 1) + density *= 0.5; /* * Using the average tuples per page, calculate how far into the @@ -596,7 +604,11 @@ scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq, block += Min(offset / density, 1.0); } - selec = block / (double) vardata->rel->pages; + /* + * Again, the last page has only half weight when converting the + * relative block number to a selectivity. + */ + selec = block / (vardata->rel->pages - 0.5); /* * We'll have one less tuple for "<" and one additional tuple for -- 2.7.4