Что будет если повесить индекс на каждое поле таблицы и почему это плохая идея
Что проверяют
Понимаете ли вы, что индекс это не бесплатное ускорение, а структура, которую база обязана поддерживать при каждой записи. У бэкендера на Java вопрос обычно вырастает из жалобы на медленные вставки через Hibernate.
Как отвечать
Скажите, что чтение ускорится не так сильно, как кажется, а запись подорожает предсказуемо. Каждая вставка обновляет все индексы таблицы: вместо одной записи вы платите за столько деревьев, сколько индексов создали. Обновление строки дорожает так же, а в PostgreSQL лишний индекс на изменяемой колонке ещё и запрещает оптимизацию, при которой новая версия строки не требует правки индексов.
Дальше назовите остальную цену:
- место на диске и вытеснение полезных страниц из кэша;
- работа планировщика: вариантов больше, оценки кардинальности ошибаются чаще, и он может выбрать не тот индекс;
- одиночные индексы не заменяют составной. Запрос по двум условиям в общем случае нормально отрабатывает только с индексом по обеим колонкам в правильном порядке;
- на колонках с низкой избирательностью, вроде флага или статуса из трёх значений, индекс просто не будет использован, планировщик предпочтёт последовательное чтение.
Правильный подход: индексы заводятся под конкретные запросы. Собрали медленные запросы, посмотрели план, добавили индекс, проверили план снова, а неиспользуемые убрали по системной статистике.
Где спотыкаются
Говорят только про место на диске. Это самая дешёвая часть, а больно становится от деградации вставок и от долгого построения индекса на большой таблице.
Второе: не умеют показать план. На вопрос «как вы поймёте, что индекс нужен» ждут EXPLAIN ANALYZE и разговор про способ доступа и оценку строк, а не рассуждение о том, что по полю часто ищут.
Третье: забывают про порядок колонок. Составной индекс работает по левому префиксу, поэтому индекс по паре колонок бесполезен для запроса только по второй из них, и это чаще причина жалобы «индекс есть, а поиск медленный», чем нехватка индексов.