Эффективно ли индексировать булевые поля в базах данных и в каких случаях это оправдано?

Ответ

В общем случае, индексировать булевые поля неэффективно.

Основная проблема: Низкая кардинальность

Индекс работает эффективно, когда он помогает базе данных быстро отсеять большую часть строк. У булевого поля всего два возможных значения (true и false). Это называется низкой кардинальностью (или низкой селективностью).

Если значения распределены примерно 50/50 (например, поле is_active), то при поиске по WHERE is_active = true индекс в лучшем случае укажет на половину таблицы. В такой ситуации планировщик запросов СУБД (например, PostgreSQL или MySQL) скорее всего выберет полное сканирование таблицы (Full Table Scan), так как это будет быстрее, чем сначала обращаться к индексу, а затем к таблице.

Когда индексирование булевых полей оправдано?

Есть два основных случая, когда такой индекс может быть полезен:

  1. Сильно искаженное распределение данных. Если одно из значений встречается крайне редко. Например, в таблице users есть поле is_admin, и только 0.1% пользователей являются администраторами. Запрос SELECT * FROM users WHERE is_admin = true; будет очень селективным, и индекс на этом поле значительно ускорит поиск.

  2. Использование частичных (Partial) или фильтрованных (Filtered) индексов. Это наиболее правильный подход. Вы можете создать индекс только для того значения, которое вас интересует. Это делает индекс маленьким и очень быстрым.

    Пример для PostgreSQL:

    -- Индексируем только активных пользователей
    CREATE INDEX idx_users_active ON users (is_active) WHERE is_active = true;

    Такой индекс будет использоваться только для запросов вида WHERE is_active = true.

Вывод:

Избегайте стандартных индексов на булевых полях, если распределение данных близко к 50/50. Если данные сильно искажены или вам нужно часто фильтровать по одному конкретному значению — используйте частичные индексы. Всегда проверяйте план выполнения запроса с помощью EXPLAIN.