Самый дорогой индекс - добавленный наугад

Медленный 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, а наблюдаемое поведение системы.

А у вас какой был самый бесполезный индекс, добавленный "на всякий случай"?

#PostgreSQL #backend #dotnet #архитектура