Ответ
В общем случае, индексировать булевые поля неэффективно.
Основная проблема: Низкая кардинальность
Индекс работает эффективно, когда он помогает базе данных быстро отсеять большую часть строк. У булевого поля всего два возможных значения (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.
Ответ 18+ 🔞
Давай разберём этот вопрос про индексы на булевых полях, а то народ часто наступает на эти грабли, как слепой крот на вертел.
Вот представь себе, блядь, обычное поле is_active в таблице пользователей. Всего два значения: true и false. Кардинальность — хуй да маленько. Планировщик запроса смотрит на это и думает: «Ну и нахуя мне тут индекс, если по нему я отсею максимум половину таблицы?». И он прав, ёпта! Полное сканирование таблицы часто оказывается быстрее, чем прыжки: сначала в индекс, а потом по ссылкам обратно в таблицу. Всё, накрылся наш индекс медным тазом, ресурсы потрачены зря.
Но! Есть же, сука, исключения, где этот индекс выстрелит, как хитрая жопа из засады.
-
Сильно перекошенное распределение. Допустим, у тебя поле
is_banned. Забаненных — 0.1%, а нормальных пользователей — 99.9%. Вот тогда запрос «найди всех забаненных уёбков» будет охуенно селективным, и индекс наis_bannedстанет твоим лучшим другом. Планировщик его схавает и скажет спасибо. -
Частичные (Partial) индексы — вот где магия, блядь! Это самый каноничный способ работы с булевыми полями. Зачем индексировать всё подряд, если тебе нужно только одно значение? Создаёшь индекс не на всё поле, а только на интересующий тебя кусок.
Смотри, как это выглядит в PostgreSQL:
-- Индексируем только активных пользователей, ебать его в сраку CREATE INDEX idx_users_active ON users (is_active) WHERE is_active = true;Такой индекс — маленький, быстрый и целенаправленный, как удар вилкой в глаз. Он будет использоваться только для запросов вида
WHERE is_active = true. Красота, ёперный театр!
Итог, Колян: Не лепи индекс на булево поле просто так, от скуки. Сначала посмотри на распределение данных. Если оно 50/50 — забей хуй. Если нужно ловить редкие значения — используй частичные индексы. И всегда, блядь, смотри план запроса через EXPLAIN, а не гадай на кофейной гуще.