A BRIN (block range index) stores compact summaries for ranges of physical table pages instead of indexing every row. It works best when column values follow the table’s physical order, such as append-only timestamps in a time-series table. Queries use matching summaries to skip unrelated page ranges, then scan the remaining pages. section 9.7.2 section 10.6
Use a BRIN index when these conditions fit:
- Choose columns whose values are strongly correlated with their physical location, especially timestamps in append-only tables. section 9.7.2
- Prefer BRIN when index size matters on large tables; its range summaries can be far smaller than equivalent B-tree indexes. section 9.7.2 section 10.6
- Expect less benefit when values are stored without a useful physical order, because more page ranges may need scanning. section 10.6
Create and inspect a time-series BRIN index
Create the index with an explicit access method:\n\nCREATE INDEX heart_rate_brin_idx\nON watch.heart_rate_measurements\nUSING brin (recorded_at);\n\nA size query can compare index relations across TimescaleDB chunks. The documented output shows BRIN indexes at 24 kB while listed B-tree indexes range from 1,432 kB to 3,896 kB. After removing the B-tree index, an execution plan for a one-day timestamp filter uses a Bitmap Heap Scan and reports 65,452 rows removed by index recheck, illustrating that BRIN narrows page ranges rather than identifying every matching row directly. section 9.7.2
Figure 9.1 The measurement time (recorded_at column) is always greater in rows added last to the page.
Visualizes how increasing measurement times accumulate within a physical page, making page-range summaries useful. section 9.7.2
