Плохо ли навешивать индексы на все поля и почему
Что проверяют
Понимаете ли вы цену индекса и умеете ли связать её с тем, что реально уходит в базу из приложения. У джависта вопрос почти всегда упирается в Hibernate: запросы генерирует ORM, и кандидат, ни разу не смотревший на них в логе, подбирает индексы наугад.
Как отвечать
Индекс ускоряет поиск и замедляет запись: на каждый INSERT, UPDATE и DELETE обновляются все индексы по затронутым колонкам, плюс место на диске и конкуренция за кэш. Поэтому индексы ставят под запросы, а не под поля.
Практический порядок для приложения на Spring:
- включить показ SQL или перехватчик запросов и посмотреть, что на самом деле генерирует Hibernate. Ленивые связи и выборка по спецификации дают совсем не тот текст, который ожидаешь по коду репозитория;
- снять план (
EXPLAIN ANALYZE) на объёме, похожем на боевой, а не на локальной базе с сотней строк; - добавить индекс под конкретное условие, чаще составной: для фильтра по двум колонкам и сортировки по третьей один продуманный индекс полезнее трёх одиночных, а порядок колонок определяет, какие запросы он закроет;
- держать индексы в миграциях Liquibase или Flyway, а не полагаться на генерацию схемы из аннотаций:
ddl-autoв проде не используют.
Отдельно скажите, что часть проблем производительности индексами не лечится. Классический N+1 от ленивой загрузки это не медленный запрос, а тысяча быстрых, и решается он выборкой со join fetch, графом сущностей или батчингом.
Где спотыкаются
Считают, что раз запрос медленный, нужен ещё индекс. Сначала смотрят план: часто там полное сканирование из-за функции над колонкой или несовпадения типов, и новый индекс просто не будет использован.
Вторая ошибка: забывать про уникальные индексы. Уникальность это требование корректности, а не оптимизация, и в конкурентной среде уникальный индекс единственное, что реально защищает от дублей, в отличие от проверки «сначала выбрать, потом вставить» в коде сервиса.
Третья: игнорировать пакетные операции. Заливка справочника батчем в таблицу с десятком индексов идёт мучительно долго. Индексы на время такой загрузки отключают или создают после неё, и об этом на собеседовании вспоминают редко.