Oracle Bitmap Index vs B-tree Index: When to Use Each
B-tree is Oracle's default, all-purpose index. Bitmap is a specialised structure for low-cardinality columns on read-heavy tables — and a real risk on tables with frequent writes. Here's the difference, and the locking gotcha that decides which one you actually want.
Two different structures for two different jobs
Oracle supports two fundamentally different index structures: B-tree (the default, used almost everywhere) and bitmap (a specialised structure for a specific kind of column and workload). Picking the wrong one doesn't just cost performance — for bitmap indexes on a heavily-written table, it can cause serious locking problems.
B-tree vs bitmap at a glance
| B-tree | Bitmap | |
|---|---|---|
| Best for | high-cardinality columns (many distinct values) | low-cardinality columns (few distinct values — status flags, gender, region) |
| Storage | one index entry per row, pointing to a ROWID | a compressed bitmap per distinct value, one bit per row |
| Combining multiple indexes | usually one index per access path | AND/OR bitmaps together efficiently — the basis of star-query optimisation in data warehouses |
| Concurrent DML (INSERT/UPDATE/DELETE) | row-level locking — safe for OLTP | a single bitmap segment covers a range of rows — updating one row can block others updating different rows in that same range |
| Typical use case | OLTP: primary keys, foreign keys, unique lookups | read-heavy analytics/data-warehouse tables with low-cardinality filter columns |
| Availability | every Oracle edition | typically an Enterprise Edition feature — confirm against your current licence |
Creating each
Same syntax family, different keyword.
-- B-tree (default — no keyword needed)
CREATE INDEX idx_emp_email ON employees (email);
-- Bitmap
CREATE BITMAP INDEX idx_emp_status ON employees (employment_status);
The concurrency gotcha
This is the fact that actually matters in practice: a bitmap index entry doesn't map to a single row the way a B-tree entry does — it maps to a range of rows via a compressed bitmap segment. When one session updates a row, Oracle has to lock the entire bitmap segment covering that row's range, not just the row. On a table with frequent concurrent updates, this can turn what looks like unrelated updates into serious lock contention — the reason bitmap indexes are recommended for read-mostly analytical tables, and actively discouraged on busy OLTP tables.