Почему плохо вводить индексы для каждой колонки
Что проверяют
Понимаете ли вы, что индекс это не настройка, а вторая структура данных, которую база обязана держать в согласии с таблицей. Заодно смотрят, чем вы руководствуетесь при её создании: планом запроса на реальных данных или привычкой добавить индекс на всякий случай.
Как отвечать
Начните с цены записи. Каждый индекс это отдельное дерево: один INSERT превращается в запись строки плюс правку всех индексов, UPDATE индексируемой колонки означает удаление и вставку ключа, и всё это дополнительно попадает в журнал. Десяток индексов на горячей таблице превращает дешёвую вставку в самую тяжёлую операцию сервиса.
Дальше скажите, что большая часть таких индексов всё равно не работает:
- по колонке с двумя-тремя значениями (флаг, статус) планировщик обычно выбирает последовательное чтение, потому что через индекс придётся достать почти всю таблицу;
- отдельные индексы по
aи поbне заменяют составной по(a, b), а составной уже закрывает запросы поa, и одиночный становится лишним; - неиспользуемый индекс всё равно обновляется, занимает место и вытесняет из кэша страницы с данными, за счёт которых запросы и работают быстро.
Закончите тем, как проверяете себя: план запроса на объёме, близком к боевому, и системная статистика обращений к индексам, по ней видно те, к которым не было ни одного обращения. Их удаляют, а частые запросы закрывают небольшим набором составных и частичных индексов.
Где спотыкаются
Называют круглый порог, вроде «больше десяти индексов уже плохо». Такого числа нет: справочнику с редкой записью много индексов не мешает, а таблице событий лишним бывает и третий.
Сводят всё к месту на диске. Место дешевле остального, дороже обходятся просевшая запись и вымытый кэш, а на больших таблицах ещё и построение индекса под нагрузкой.
Не учитывают селективность и порядок колонок. Индекс по полю, где почти все значения одинаковы, бесполезен, а составной индекс запрос без первой колонки в условии обычно не задействует.