]> granicus.if.org Git - postgresql/commitdiff
Add commentary explaining why MaxIndexTuplesPerPage calculation is safe.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 14 Apr 2018 16:33:15 +0000 (12:33 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 14 Apr 2018 16:33:15 +0000 (12:33 -0400)
MaxIndexTuplesPerPage ignores the fact that btree indexes sometimes
store tuples with no data payload.  But it also ignores the possibility
of "special space" on index pages, which offsets that, so that the
result isn't an underestimate.  This all seems worth documenting, though.

In passing, remove #define MinIndexTupleSize, which was added by
commit 2c03216d8 but not used in that commit nor later ones.

Comment text by me; issue noticed by Peter Geoghegan.

Discussion: https://postgr.es/m/CAH2-WzkQmb54Kbx-YHXstRKXcNc+_87jwV3DRb54xcybLR7Oig@mail.gmail.com

src/include/access/itup.h

index 04526a8e59fb198b2716b75386aa0eed0b52c324..555434ca803cbef5ad6e2258ac655dd34414a72a 100644 (file)
@@ -132,8 +132,16 @@ typedef IndexAttributeBitMapData * IndexAttributeBitMap;
  * bitmap, so we can safely assume it's at least 1 byte bigger than a bare
  * IndexTupleData struct.  We arrive at the divisor because each tuple
  * must be maxaligned, and it must have an associated item pointer.
+ *
+ * To be index-type-independent, this does not account for any special space
+ * on the page, and is thus conservative.
+ *
+ * Note: in btree non-leaf pages, the first tuple has no key (it's implicitly
+ * minus infinity), thus breaking the "at least 1 byte bigger" assumption.
+ * On such a page, N tuples could take one MAXALIGN quantum less space than
+ * estimated here, seemingly allowing one more tuple than estimated here.
+ * But such a page always has at least MAXALIGN special space, so we're safe.
  */
-#define MinIndexTupleSize MAXALIGN(sizeof(IndexTupleData) + 1)
 #define MaxIndexTuplesPerPage  \
        ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
                        (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))