Окружение:
У нас есть два 32-разрядных компьютера с Windows Server 2003 R2 под управлением SQL Server 2005. Аппаратные конфигурации - это идентичные серверы с процессором Xeon 5160, 4 ГБ ОЗУ и 13 ГБ RAID0. Флаги AWE и / 3GB не включены.
Серверы были установлены параллельно с использованием предварительно определенного контрольного списка установки, и ВСЕ установленное программное обеспечение одинаково на обеих машинах.
Все установки SQL-сервера и уровень исправлений, которые мы проверяем, идентичны. Одно из отличий состоит в том, что TEMPDB составляет 400 МБ на быстрой машине и 1,2 ГБ на медленной. Однако в обоих случаях мы не видим распределения TEMPDB.
Проблема:
Существует хранимая процедура, которая выполняется за 2 секунды на одной, но 15 минут на другой. В течение дополнительных 15 минут активность диска практически отсутствует, использование памяти не изменяется, но одно ядро ЦП закреплено на все 100%.
Такое поведение сохраняется даже при резервном копировании баз данных из одной и восстановлении в другой.
Поскольку это хранимая процедура, монитор активности и профилировщик не показывают нам каких-либо подробностей о том, где в хранимой процедуре происходит такая высокая загрузка ЦП.
Вопрос:
На что еще мы должны смотреть?
Следовать за:
Замедление происходит в операторах FETCH NEXT для следующего определения курсора:
DECLARE C CURSOR FOR
SELECT X, Y
FROM dbo.A
WHERE X NOT IN (SELECT X FROM dbo.B)
AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
...
Каждый из операторов FETCH - в таблице, содержащей только около 1000 строк - требует около 7,25 минут. (Нет, я не знаю, почему он делает два подряд, нужно спросить разработчиков, но он работает правильно на обоих серверах).
Я немного подозрительно отношусь к этому «NOT IN (SELECT ...)», поскольку похоже, что Virtual Reads действительно высоко.
источник
Ответы:
Используя методологию устранения неполадок с производительностью, такую как « Ожидания» и «Очереди», выявляют причину высокой загрузки ЦП, затем можно рекомендовать соответствующие действия после выявления узкого места.
источник
SQL Server выбирает другой план в другом окне.
Восстановление обычно удаляет проблемы, основанные на статистике, поэтому я бы посмотрел на различия сервера.
Сначала несколько грубых проверок. Не предполагайте: проверьте
Затем прыгайте в глубокий конец, как и в ответе Ремуса.
источник
Если все остальные вещи равны, вероятно (согласно ответу @ gbn), что на каждом сервере генерируется другой план выполнения. В качестве академического упражнения было бы интересно увидеть оба плана, поэтому возьмите их из кэша планов на каждом сервере и добавьте их в свой вопрос, если это возможно. Затем мы можем определить различия в планах, которые вызывают такие большие различия в производительности.
Для быстрого исправления взгляните на подсказку USE PLAN . Это позволяет прикрепить хороший план с быстрого сервера к хранимой процедуре на медленном сервере.
Редактировать: следующее обновление: курсор
Еще один вариант вашего запроса, который я не вижу в других ответах:
источник
Приколите меня и попробуйте заменить:
с этим:
Я не думаю, что это должно проявиться как проблема с производительностью в части кода FETCH NEXT FROM, но у меня еще не было инъекций кофеина. Попробуйте мое предложение и дайте мне знать.
Надеюсь это поможет,
Matt
источник
Проверьте свои индексы и обновите всю свою статистику. У меня была очень схожая проблема, и оказалось, что статистика на одной машине была плохой.
источник
Я испытывал такое же поведение дважды, и я скажу вам, что исправило это каждый раз:
1.) Я добавил подсказку WITH RECOMPILE к хранимой процедуре, потому что кэшированный план был ужасен.
2.) Я изменил хранимую процедуру, чтобы использовать временные таблицы вместо табличных переменных.
Я надеюсь, что любой из этих поможет. Удачи.
источник