Самый дорогой индекс - добавленный наугад
Медленный SQL редко стоит лечить индексом с первой попытки.
Запрос тормозит. Первая реакция понятна: добавить индекс и посмотреть, стало ли быстрее. Иногда срабатывает. Иногда мы просто покупаем дополнительную запись на диск, более дорогие INSERT/UPDATE и ещё один объект, который нужно обслуживать.
Я бы сначала собрал короткую карту проблемы:
1. Взял реальный запрос с реальными параметрами. 2. Посмотрел EXPLAIN (ANALYZE, BUFFERS) в безопасной среде. 3. Сравнил estimated rows и actual rows. Большой разрыв часто указывает не на отсутствие индекса, а на устаревшую статистику или перекос данных. 4. Проверил чтения, Heap Fetches, сортировки и временные файлы. Одного Total Cost недостаточно. 5. Исключил блокировки, долгие транзакции и idle in transaction. Иногда SQL ждёт, а не работает. 6. Только после этого выбирал лекарство: индекс, переписывание запроса, ANALYZE, настройку autovacuum, work_mem или изменение модели доступа.
Важный нюанс: EXPLAIN ANALYZE действительно выполняет запрос. Для изменяющих данные операций запускать его в production без защиты - отличный способ превратить диагностику в инцидент.
Главная мысль простая: оптимизировать нужно не текст SQL, а наблюдаемое поведение системы.
А у вас какой был самый бесполезный индекс, добавленный "на всякий случай"?