PostgreSQL Index Bloat: Why VACUUM Won't Shrink Indexes and How to Fix It
A PostgreSQL database was found to have indexes up to six times larger than the heap data they referenced, with one table's 4.6 GB heap carrying 30 GB of indexes. Standard VACUUM only marks dead index entries as reusable and reclaims fully empty pages, but sparse b-tree pages with even one surviving key remain allocated indefinitely since b-trees do not merge sparse neighbours. The recommended fix is REINDEX INDEX CONCURRENTLY run one index at a time, which avoids locking the table and limits peak extra disk usage to the size of one new index. Index bloat can be measured using pgstatindex's avg_leaf_density field, with values significantly below the 90% b-tree default fillfactor indicating bloat, and recovered space can be estimated as current_size multiplied by density divided by 90. VACUUM FULL is the wrong remedy for index bloat as it targets heap bloat, requires an ACCESS EXCLUSIVE lock, and needs free space equal to the entire table size.
This is an AI-generated summary. ShortSingh links to the original source for the complete article.
Discussion (0)
Log in to join the discussion and vote.
Log in