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

Ответ

Как правило, нет. Булево поле (BOOLEAN, TINYINT(1)) имеет очень низкую кардинальность (всего 2-3 значения: true, false, возможно NULL). В такой ситуации оптимизатор СУБД часто предпочтет полное сканирование таблицы (full table scan) использованию индекса, так как это будет быстрее.

Когда индекс на булевом поле может быть полезен:

  1. Сильно неравномерное распределение данных. Например, если в таблице из миллионов строк только несколько тысяч записей имеют значение is_active = true, то индекс поможет быстро их найти.
  2. Как часть составного (композитного) индекса. Булево поле может быть полезным первым или последним ключом в индексе, если запросы часто фильтруют по нему в сочетании с другими полями.

Пример (PostgreSQL):

-- Скорее всего, бесполезный индекс (данные распределены 50/50)
CREATE INDEX idx_order_completed ON orders(is_completed);

-- Потенциально полезный составной индекс
CREATE INDEX idx_active_user_created ON users(is_active, created_at) WHERE is_active = true;

-- Более эффективная альтернатива для фильтрации по флагу — партиционирование таблицы.

На практике решение об индексации всегда следует проверять через EXPLAIN ANALYZE для конкретных запросов и объема данных.

Ответ 18+ 🔞

А, ну это классика, блядь! Смотри, тут всё просто, как три копейки. В 99% случаев индекс на булевом поле — это пиздец какая бесполезная затея, ядрёна вошь. Представь себе: у тебя поле, которое может быть либо true, либо false, ну или ещё NULL прилепится. Всего-то два-три значения на всю таблицу! Ну какая тут, нахуй, кардинальность? Нулевая, пиздец.

Оптимизатор базы — он не дурак, чувак. Он посмотрит на эту хуйню и подумает: "Ёпта, да зачем мне по индексу скакать, если проще всю таблицу целиком прочитать, это будет быстрее!" И будет прав, сука. Полное сканирование (full table scan) в таком случае — это как ехать на работу на метро, а не переться через все дворы на велике, срезая путь через каждую арку.

Но, как и везде, есть свои "но", хитрая жопа. Индекс может выстрелить в двух сценариях:

  1. Данные распределены пиздец как криво. Ну, типа, у тебя таблица на 10 миллионов записей, а значение true только у 5 тысяч. Вот тогда да, индекс — как спасательный круг. Найти эти несколько тысяч по индексу — раз плюнуть. А вот если у тебя там 50 на 50, то забудь, как страшный сон. Терпения ноль ебать, пока такой индекс строится.

  2. Он часть составного индекса. Вот это уже дельно. Допустим, у тебя часто идут запросы типа "покажи мне всех активных юзеров, отсортированных по дате регистрации". Тогда индекс (is_active, created_at) — это огонь. Особенно если добавить WHERE is_active = true. База сразу поймёт, куда смотреть.

Смотри на примере, чтобы совсем доходило:

-- Вот этот индекс — скорее всего, манда с ушами. Потратишь время на создание, а толку — хуй с горы.
CREATE INDEX idx_order_completed ON orders(is_completed);

-- А вот это уже умная мысль. Работать будет, если `is_active = true` — это редкие зверьки.
CREATE INDEX idx_active_user_created ON users(is_active, created_at) WHERE is_active = true;

Но запомни, чувак, главное правило: доверия ебать ноль любым советам, включая этот. Не надо тыкать индексы наобум. Берёшь свой конкретный, самый жирный и медленный запрос, пишешь перед ним EXPLAIN ANALYZE и смотришь, что тебе движок базы насоветует. Вот это — святая правда. А то накрутишь индексов, а потом удивляешься, почему всё стало работать, как будто на дворе 2002-й год.