Вопросы
Очень часто ко мне обращаются с вопросами типа:
- «Наша хранимая процедура работала хорошо, а сейчас работает плохо»
- «Иногда, наша хранимая процедура работает очень долго»
- «Скорость выполнения хранимой процедуры крайней сильно зависит от переданных в неё параметров»
Что делать
Можно использовать множество методик, чтобы понять и решить проблему:
- Иногда достаточно просто единоразово или на регулярной основе сбрасывать план определённый хранимой процедуры через
sp_recompile 'MyProcName'
- Так же можно добавить параметр к хранимой процедуре RECOMPILE. При таком способе план запроса не будет сохраняться в кэше и будет строиться каждый раз заново, что позволит получать каждый раз максимально актуальный план. Из минусов — на это требуются некоторые ресурсы.
- Используя параметр хранимой процедуры FOR UNKNOWN, можно усреднить план выполнение . При это SQL Sever будет строить «усреднённый план» для всех параметров, что может ухудшить выполнение скорости большинства запросов, но при этом сгладит большие скачки с определёнными параметрами. Можно попробовать таким образом гарантировать время выполнения хранимой процедуры
- И т.д.
Реальный случай из жизни
Эта статья бы не входила в рубрику «Вопрос-Решение», если бы не содержала информацию о реальной проблеме с хранимой процедурой. На Хабре есть отличная статья по этому вопросу, называется «Как SQL Server каждые два-три часа переключался на использование не оптимального плана выполнения запроса». Краткое описание проблемы:
В чём проявляется проблема:
Запускаю хранимую процедуру (хранимку) по выборке данных для отчета — выполняется три секунды, смотрю профайлером на бою — у пользователей те же результаты. Но проходит три часа и та же хранимка, с теми же параметрами выполняется уже 2 минуты, и аналогично у пользователей. Причём данные в используемые таблицы не вставлялись/удалялись, окружение не меняли и админы не делали настроек.
Обратите внимание, что автор пишет:
Профайлер не отображает на планах выполнения Actual Number Of Rows, причем пишет не n/a, а ноль. Нужно помнить об этом!
Но это не совсем так. На самом деле крайне редко встречается значение 0 в Actual Number of Rows, в большинстве случаев значение присутствует.