Стоит ли создавать индекс на булевом поле с низкой вариативностью и как это влияет на производительность?
Что проверяют
Понимаете ли вы, что индексом пользуется планировщик по статистике, а не разработчик по типу колонки. Ждут слово «селективность» и умение назвать случаи, когда индекс по булеву полю всё-таки нужен.
Как отвечать
Сам по себе булев тип ничего не решает, решает распределение значений. Если истина и ложь делят таблицу примерно поровну, отдельный индекс бесполезен: планировщик посчитает, что прочитать таблицу целиком дешевле, чем прыгать по ней через индекс, и будет прав. Такой индекс займёт место и будет обновляться при каждой записи, не принося пользы.
Другое дело перекошенное распределение. Если флаг взведён у крохотной доли строк и запросы ищут именно её, индекс работает отлично. Так устроены очереди задач: необработанных записей мало, выбирают только их.
Дальше назовите два приёма, которых обычно и ждут:
- частичный индекс, где условие по флагу вынесено в само определение индекса. В него попадают только нужные строки, он в разы меньше и трогается только при смене флага;
- составной индекс, где флаг идёт рядом с колонкой, которая реально сужает выборку. Порядок важен: первой ставится отбирающая колонка, флаг добавляется, чтобы отсечь лишнее и по возможности закрыть запрос данными самого индекса.
Полезно упомянуть, что набор типов индексов у разных СУБД отличается, и там, где есть отдельный тип под колонки с малым числом значений, ответ меняется, но платят за него блокировками при записи.
Где спотыкаются
Судят по типу колонки, а не по данным. Правильный ход это посмотреть фактическое распределение значений и план запроса, а не рассуждать умозрительно про два состояния.
Второе: строят индекс и не проверяют, что он используется. Если запрос заворачивает колонку в функцию или сравнивает её с выражением другого типа, обычный индекс не применится, и план останется прежним.
Третье: забывают про неопределённое значение. Колонка, допускающая пустоту, это уже три состояния, и условие на неравенство истине не вернёт строки с неизвестным значением. Именно этот случай чаще всего и ломает выборку.