BitmapOr
Appears in EXPLAIN asBitmapOr
Unions bitmaps from multiple indexes (OR).
What it is
BitmapOr combines the bitmaps from several Bitmap Index Scans by union, keeping rows that match any of them — letting an OR across indexed columns still use indexes.
When the planner picks it
When OR-ed conditions can each be served by an index and unioning the results is cheaper than a sequential scan.
Is it good or bad?
Good — it's how OR conditions stay indexed instead of forcing a full scan. Make sure each OR branch actually has a supporting index.
In depth
How OR stays indexed
BitmapOr unions bitmaps from sibling Bitmap Index Scans, returning rows that
match any of them. Without it, an OR across columns from different indexes
would defeat indexing — the planner would fall back to a sequential scan to
evaluate the expression row by row.
Bitmap Heap Scan on events
Recheck Cond: …
-> BitmapOr
-> Bitmap Index Scan on events_user_idx
Index Cond: user_id = 42
-> Bitmap Index Scan on events_session_idx
Index Cond: session_id = '…'
Make sure each branch has an index
A BitmapOr is only useful if every branch can find its own index. A single non-indexed branch forces the planner to abandon the bitmap plan entirely: the query devolves to a Seq Scan with a filter that touches every row.
So when you write a multi-branch OR, look at the plan after each branch is added — if the bitmap plan disappears, that branch needs a (partial, expression, or composite) index.
Lossy bitmaps still apply
The combined bitmap is subject to the same work_mem budget. Large OR results
can spill into block-level (lossy) form and require a per-row recheck at the
heap scan; raising work_mem for the query brings it back to exact.