Плохо ли навешивать индексы на все поля и почему
Что проверяют
Понимаете ли вы, что индекс это компромисс, а не бесплатное ускорение. В работе с данными компромисс виднее, чем в обычном бэкенде: нагрузка идёт пачками, таблицы широкие, и лишний индекс бьёт по загрузке сильнее, чем помогает отчёту.
Как отвечать
Да, плохо, и объяснить чем:
- каждая вставка и каждое обновление тянут за собой перестройку всех индексов по затронутым колонкам. Ночная заливка миллионов строк в таблицу с десятком индексов идёт в разы дольше;
- индексы занимают место и вытесняют полезные данные из кэша;
- планировщик всё равно не возьмёт индекс с плохой избирательностью: по колонке со значениями «да» и «нет» последовательное чтение дешевле, и это правильное решение;
- отдельные индексы на каждое поле не заменяют составной. Для условия по двум колонкам нужен один индекс по обеим, и порядок колонок в нём важен: он работает по левому префиксу.
Что предложить вместо «навесить на всё»: индексы ставятся под конкретные запросы, а не под колонки. Смотрим план (EXPLAIN ANALYZE), находим тяжёлые сканирования, добавляем то, что реально попало в план, и удаляем неиспользуемые, благо статистика обращений к индексам в PostgreSQL доступна. Перед массовой загрузкой индексы лучше строить после заливки, а не до. Сильный ход: заметить, что в колоночных аналитических СУБД привычных B-tree индексов нет вовсе, там работают сортировка по ключу и разреженный индекс, так что совет про индексы туда просто не переносится.
Где спотыкаются
Называют только замедление записи. Это верно, но неполно: без избирательности и составных индексов ответ выглядит заученным, а спрашивают дальше как раз про них.
Вторая ошибка: считать, что индекс на поле гарантирует его использование. Функция над колонкой в условии, неявное приведение типа, поиск вида LIKE '%abc' сводят индекс на нет, если он не создан специально под такое выражение.
Третья: путать уникальный индекс с оптимизацией. Он прежде всего ограничение целостности, и его не убирают ради скорости вставки. А вот десяток похожих индексов, отличающихся порядком колонок, почти всегда схлопывается в один или два.