Bitmap индекс в Oracle — когда ускоряет, а когда мешает
Введение
Битовые индексы — мощный инструмент в Oracle, но работают не везде. В этом посте — просто и по делу: когда их использовать, а когда лучше обойти стороной.
Что такое битовый индекс?
В отличие от классического B-tree индекса, который хранит ссылки на строки с конкретными значениями, битовый индекс использует битовые карты: для каждого уникального значения создаётся "битовая маска", где каждая строка таблицы — это позиция (бит). Один бит = одна строка.
Такой подход суперэффективен, когда: 1. значений немного (низкая кардинальность) 2. частые фильтры или группировки по этому полю.
Когда он полезен?
Посмотрим на таблицу `demo_customers`.
Есть поле `is_active`, которое может быть `'Y'` или `'N'`.
Угадаете, сколько уникальных значений? Правильно — два.
Создаем индекс
Теперь запросы вроде:
будут отрабатывать быстрее — особенно на больших таблицах.
Аналогично, если вы часто строите отчёты по `region`, и количество регионов ограничено (например, 10–20), создаём:
Это даст буст производительности при таких запросах:
Заметьте: Oracle может эффективно объединять несколько битовых индексов в одном запросе — это ещё один плюс.
Когда НЕ стоит использовать битовые индексы?
Вот где начинаются подводные камни:
1. Частые DML-операции (INSERT/UPDATE/DELETE): битовый индекс тяжеловат на обновления. Любое изменение строки может затронуть много битов — и Oracle будет блокировать больше, чем хотелось бы.
2. Высокая кардинальность — например, индекс на customer_id или product_id точно не стоит делать битовым: для каждого значения будет почти свой отдельный бит, и индекс станет больше самой таблицы.
3. В многопользовательской среде с конкурентной записью — возможны блокировки.
Массовые изменения — осторожно!
Допустим, вы обновляете тысячи строк в `demo_orders`:
Битовый индекс is_active здесь будет тормозить: Oracle должен будет перестраивать множество битов, возможно с блокировками. В OLTP-сценариях лучше использовать обычный B-tree или вообще обойтись без индекса.
Проверяем скорость с и без индекса
Резюме
Используй битовый индекс, если
- Поле с низкой кардинальностью (`Y/N`, фиксированный список значений)
- Часто идёт фильтрация, группировка, аналитика
- Таблица читается чаще, чем изменяется
Избегай, если
- Поле с уникальными или почти уникальными значениями
- Частые INSERT/UPDATE/DELETE
- Сценарии с высокой конкурентностью
Полезные ссылки
Файлы и скрипты
Исходные файлы можно найти в (GIT).
Выводы
Битовый индекс — отличный инструмент, но не волшебная палочка. Бери и применяй — но не везде!
P.S. Если что-то не работает или нужен архив в другом формате — напишите мне.