Коллеги, давайте разберем план выполнения. У тяжелого запроса обычно три источника боли: лишние чтения, плохая селективность и неудачный порядок join’ов. Если первым делом смотреть только на индекс, можно просто ускорить неправильный путь.
Что проверять в первую очередь:
— есть ли full scan там, где ожидался seek;
— не раздувает ли join промежуточный набор строк;
— не делает ли запрос сортировку или hash aggregate на огромном объеме;
— не тянет ли он лишние колонки, которые потом никто не использует.
Схема простая, но дьявол кроется в статистике. Когда оценка кардинальности ошибается, оптимизатор выбирает удобный на бумаге, но дорогой в реальности план. Посмотрим, что тут с I/O в реальности: если один оператор читает миллионы строк ради нескольких сотен результата, индекс — не первое лекарство, а повод пересобрать фильтры, предикаты и порядок агрегации.
Рабочий прием: сначала упростить запрос логически. Вынести повторяющиеся подзапросы, убрать функции из условий, заменить лишние OR на явные ветки, ограничить выборку раньше. Потом уже сравнивать планы и нагрузку на диск, а не гадать по ощущениям. В продакшене так лучше не делать, и вот почему: “красивый” рефакторинг без проверки может только спрятать дедлоки и усилить блокировки.
Золотое правило: сначала мониторинг, потом индексы. Если план не стал дешевле после упрощения логики, проблема чаще в данных и статистике, чем в синтаксисе.
Оптимизация производительности баз
@database_performance_tuning_arb
Сложный SQL тормозит не из-за “плохого сервера”, а из-за лишней работы внутри плана
Этот пост опубликован в Telegram-канале Оптимизация производительности баз. Подписаться можно по ссылке: @database_performance_tuning_arb.