Странная проблема с планом выполнения процедур SQL Server - PullRequest
4 голосов
/ 26 июля 2011

Мне было интересно, могли бы вы, ребята, помочь мне разобраться со странной проблемой, с которой я недавно столкнулся на SQL Server.

У меня есть хранимая процедура (давайте вызовем SPold), которая достаточно велика с большим количеством вычислений (я не могу сделать это в приложении, так как информация для около 6000 пользователей должна вернуться за один раз (я уменьшите это до 1000 на основе фамилии)). Хранимая процедура обычно выполняется за пару секунд и вызывается раз в пару минут.

Теперь утром хранимая процедура неожиданно выполнялась в 4-10 раз дольше, что приводило к нескольким тайм-аутам. Я обнаружил, что, сделав копию процедуры с новым именем (SPnew) и выполнив ее, я снова получу быстрое время выполнения. Это указывало на то, что план выполнения был проблемой с оригиналом, SPold, поэтому я решил выполнить его с перекомпиляцией. Это вернет результаты быстрее (хотя и не так быстро, как SPnew), но последующие обращения пользователей к SPold снова будут медленными. Как будто новый план не был соблюден.

Что я сделал, так это исправил, положил Exec SPnew в SPold, и теперь вызовы SPold снова быстро возвращаются.

Кто-нибудь знает, что здесь происходит? Единственное, что обновилось за одну ночь, это статистика, хотя я думаю, что это должно повлиять как на SPold, так и на SPnew.

Ответы [ 2 ]

5 голосов
/ 26 июля 2011

Похоже, что вы используете неверно кэшированный план запроса из-за перехвата параметров.

Можно ли опубликовать хранимую процедуру?

В SQL Server2005, вы можете использовать подсказку запроса OPTIMIZE FOR для предпочтительных значений параметров, чтобы исправить некоторые проблемы, связанные с анализом параметров:

OPTIMIZE FOR Инструкцииоптимизатор запросов для использования определенного значения для локальной переменной, когда запрос компилируется и оптимизируется.Значение используется только во время оптимизации запроса, а не во время выполнения запроса.OPTIMIZE FOR может противодействовать поведению оптимизатора при обнаружении параметров или может использоваться при создании направляющих планов.Для получения дополнительной информации см. Перекомпиляция хранимых процедур и Оптимизация запросов в развернутых приложениях с использованием руководств плана .

Хотя SQL Server 2005 не поддерживает OPTIMIZE FOR UNKNOWN(введено в SQL Server 2008), что устранит перехват параметров для данного параметра:

OPTION (OPTIMIZE FOR (@myParam UNKNOWN))

Вы можете добиться того же эффекта в SQL Server 2005, скопировав параметр в локальную переменную, а затем используя локальнуюпеременная в запросе.

4 голосов
/ 26 июля 2011

Я также столкнулся с двумя «странными» случаями с Sql Server 2005, которые также могут относиться к вашей проблеме.

В первом случае моя процедура выполнялась очень быстро, при запуске как dbo, ион был медленным при запуске из приложения под другой учетной записью пользователя.

Во втором случае план запроса процедуры был оптимизирован для значений параметров, с которыми процедура вызывалась в первый раз, изатем этот план затем повторно использовался и для других значений параметров, что приводило к медленному выполнению.

Для этого второго случая решением было скопировать значения параметров в локальные переменные в процедуре, а затем использовать переменные взапросы вместо параметров.

...