pgconfigurator
pgconfigurator

Bitmap Index Scan

Appears in EXPLAIN asBitmap Index Scan

Scans an index to build a bitmap of matching row locations.

What it is

A Bitmap Index Scan reads an index and produces a bitmap of all matching tuple locations, rather than fetching rows itself. The bitmap is then handed to a Bitmap Heap Scan (possibly after combining with BitmapAnd / BitmapOr).

When the planner picks it

As the index-reading half of a bitmap plan, especially when several indexes will be combined.

Is it good or bad?

A building block, not a finished result — it always appears beneath a Bitmap Heap Scan. Nothing to tune here directly; tune the heap scan and the indexes.

In depth

Half of a bitmap plan

A Bitmap Index Scan is the first phase of a bitmap plan. It reads an index and produces a bitmap of tuple identifiers (CTIDs) — locations in the heap, not the rows themselves. That bitmap is handed up to a Bitmap Heap Scan (possibly after combining with BitmapAnd / BitmapOr), which then reads the heap pages in physical order.

You won't tune anything directly on the Bitmap Index Scan; everything interesting happens above it.

What its numbers tell you

Bitmap Index Scan on big_val_idx  (cost=0..122 rows=9353 width=0)
  (actual time=0.8..0.8 rows=9851 loops=1)
  Index Cond: (val < 2000)
  • Index Cond — what the index satisfied directly. Good.
  • A small estimate vs. a huge actual hints at a row-estimate problem; the bitmap then needs more work_mem than the planner sized for, which surfaces upstream as a lossy bitmap.
  • Fast index reads here, slow heap reads upstream is the normal shape of a bitmap plan — the planner expects this asymmetry.

When several indexes combine

If a query has conditions on multiple indexed columns, the planner can run a Bitmap Index Scan per index and combine them with BitmapAnd (intersection) or BitmapOr (union). That's how an OR across two indexes stays indexed instead of forcing a seq scan.

See also