diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 5e025a7437..c6286f08ab 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -590,8 +590,10 @@ scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq, block = ItemPointerGetBlockNumberNoCheck(itemptr); /* - * If there's a useable density (tuples per page) estimate, take - * into account the fraction of a block with a lower TID offset. + * Determine the average number of tuples per page. We 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. */ density = vardata->rel->tuples / vardata->rel->pages; if (density > 0.0) @@ -603,10 +605,17 @@ scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq, selec = block / (double) vardata->rel->pages; - /* For <= and >=, one extra item is included. */ - if (iseq && vardata->rel->tuples >= 1.0) - selec += (1 / vardata->rel->tuples); + /* + * We'll have one less tuple for "<" and one additional tuple for + * ">=", the latter of which we'll reverse the selectivity for + * below, so we can simply subtract a tuple here. We can easily + * detect these two cases by iseq being equal to isgt. They'll + * either both be true or both be false. + */ + if (iseq == isgt && vardata->rel->tuples >= 1.0) + selec -= (1 / vardata->rel->tuples); + /* Finally, reverse the selectivity for the ">", ">=" case. */ if (isgt) selec = 1.0 - selec;