Другой план выполнения для одной и той же хранимой процедуры - PullRequest
4 голосов
/ 03 февраля 2009

У нас есть запрос, который занимает около 5 секунд в нашей производственной системе, но в нашей зеркальной системе (максимально идентичной производственной) и системах разработки он занимает менее 1 секунды.

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

Мы знаем, как это исправить, реорганизовав объединения и добавив подсказки, однако на данный момент было бы проще, если бы нам не пришлось вносить какие-либо изменения в SProc (Делопроизводство). Мы также попробовали sp_recompile.

Что может вызвать разницу между двумя планами запросов?

Система: SQL 2005 SP2 Enterprise на Win2k3 Enterprise

Обновление: спасибо за ваши ответы, оказывается, это была статистика. См. Резюме ниже.

Ответы [ 6 ]

12 голосов
/ 03 февраля 2009

Ваша статистика, скорее всего, устарела. Если ваши данные одинаковы, пересчитайте статистику на обоих серверах и перекомпилируйте. Затем вы должны увидеть идентичные планы запросов.

Кроме того, дважды проверьте, что ваши индексы идентичны.

3 голосов
/ 03 февраля 2009

Скорее всего статистика.

Некоторые мысли: Делаете ли вы техобслуживание в своих непроизводительных системах? (например, индексы rebuidl, которые будут перестраивать статистику)

Если да, то используете ли вы тот же коэффициент заполнения и статистическую выборку?

Регулярно ли вы восстанавливаете базу данных в тестовом режиме, так что она на 100% похожа на рабочую?

3 голосов
/ 03 февраля 2009

Являются ли данные и размер данных между вашим зеркалом и камерой максимально близкими? Если вы знаете, почему один запрос занимает больше времени, чем другой? Вы можете опубликовать более подробную информацию?

Планы выполнения в таких случаях могут отличаться из-за данных в таблицах и / или статистики. Даже в тех случаях, когда включена статистика автоматического обновления, статистика может устареть (особенно в очень больших таблицах) Вы можете обнаружить, что оптимизатор оценил, что таблица не такая большая, и выбрал сканирование таблицы или что-то подобное

2 голосов
/ 03 февраля 2009

Привязка к первому ответу может быть связана с функцией прослушивания параметров SQL Server. Он использует первое значение, которое вызвало компиляцию, чтобы помочь создать план выполнения. Обычно это хорошо, но если значение не является нормальным (или каким-то странным), это может привести к плохому плану. Это также объясняет разницу между производством и тестированием.

Отключение сниффинга параметров потребует изменения SProc, что, как я понимаю, нежелательно. Однако после использования sp_recompile передайте параметры, которые вы сочтете «нормальными», и они должны перекомпилироваться на основе этих новых параметров.

Я думаю, что поведение анализатора параметров отличается между 2005 и 2008, так что это может не сработать.

2 голосов
/ 03 февраля 2009

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

Вот простой пример того, как можно кэшировать неверный план запроса:

create proc spTest
    @id int 
as 
select * from sysobjects where @id is null or id = id 

go 

exec spTest null
-- As expected its a clustered index scan

go

exec spTest 1
-- OH no its a clustered index scan 

Попробуйте запустить Sql в QA на рабочем сервере за пределами хранимого процесса, чтобы определить, есть ли у вас проблема с устаревшей статистикой или отсутствием таинственных индексов в рабочей среде.

0 голосов
/ 03 февраля 2009

Решение было пересчитать статистику. Я упустил из виду, что, как обычно, у нас есть запланированные задачи, чтобы сделать все это, но по какой-то причине администраторы не поставили один этот сервер, Doh.

Подведем итог всем постам:

  • Проверьте настройки так же
    • Индексы
    • Размеры стола
    • Восстановление базы данных
  • Кэширование плана выполнения
    • Если запрос выполняется так же за пределами SProc, это не план выполнения
    • sp_recompile, если он отличается
    • Параметр сниффинг
  • Пересчитать статистику
...