Ответ
В общем случае, индексировать булевые поля неэффективно.
Основная проблема: Низкая кардинальность
Индекс работает эффективно, когда он помогает базе данных быстро отсеять большую часть строк. У булевого поля всего два возможных значения (true
и false
). Это называется низкой кардинальностью (или низкой селективностью).
Если значения распределены примерно 50/50 (например, поле is_active
), то при поиске по WHERE is_active = true
индекс в лучшем случае укажет на половину таблицы. В такой ситуации планировщик запросов СУБД (например, PostgreSQL или MySQL) скорее всего выберет полное сканирование таблицы (Full Table Scan), так как это будет быстрее, чем сначала обращаться к индексу, а затем к таблице.
Когда индексирование булевых полей оправдано?
Есть два основных случая, когда такой индекс может быть полезен:
-
Сильно искаженное распределение данных. Если одно из значений встречается крайне редко. Например, в таблице
users
есть полеis_admin
, и только 0.1% пользователей являются администраторами. ЗапросSELECT * FROM users WHERE is_admin = true;
будет очень селективным, и индекс на этом поле значительно ускорит поиск. -
Использование частичных (Partial) или фильтрованных (Filtered) индексов. Это наиболее правильный подход. Вы можете создать индекс только для того значения, которое вас интересует. Это делает индекс маленьким и очень быстрым.
Пример для PostgreSQL:
-- Индексируем только активных пользователей CREATE INDEX idx_users_active ON users (is_active) WHERE is_active = true;
Такой индекс будет использоваться только для запросов вида
WHERE is_active = true
.
Вывод:
Избегайте стандартных индексов на булевых полях, если распределение данных близко к 50/50. Если данные сильно искажены или вам нужно часто фильтровать по одному конкретному значению — используйте частичные индексы. Всегда проверяйте план выполнения запроса с помощью EXPLAIN
.