План запроса перекомпилируется внезапно и снижает производительность - PullRequest
0 голосов
/ 06 марта 2019

Сценарий : у нас есть простой запрос на выборку

Declare P@

SELECT TOP(1) USERID
FROM table
WHERE non_clusteredindex_column = (@P) ORDER BY PK_column DESC

Обычно он выполняется за 0,12 сек с 1 года.Но вчера, внезапно, ровно после полуночи, он начал потреблять весь мой процессор и занимать 150 секунд для выполнения.Я проверил SP_who2 и не нашел никаких мертвых блокировок и ничего, кроме этого одного запроса, потребляющего весь процессор.Я решил перезагрузить сервер, чтобы избавиться от каких-либо проблем с прослушиванием параметров или уничтожить все устаревшие соединения. Я взял трассировку профилировщика SLQ в течение 1 минуты, а затем перезапустил сервер для последующего анализа первопричин.После перезагрузки все возвращается на круги своя.Я был удивлен и с любопытством начал просматривать план выполнения в профилировщике и сравнивал его с текущим планом выполнения того же запроса.Я обнаружил, что оба разные.

План выполнения до проблемной ночи совпадает с планом выполнения после перезагрузки.(При совершенном поиске индекса )

Но план выполнения в профилировщике SQL проблемной ночи выполняет полное сканирование индекса , которое занимает весь ЦП и требует 150 секунд для выполнения.

Quesion :

Могу сказать, что план выполнения был неожиданно перекомпилирован или запрос запущен с использованием нового плана выполнения (полное сканирование) после вчерашней полуночи и после перезагрузки снованачал использовать старый и хороший план выполнения (индекс SEEK).

Q1 .Что заставило SQL-сервер внезапно использовать новый план ИСПОЛНЕНИЯ? Q2 .Что заставило SQL-сервер использовать старый и хороший план выполнения после перезагрузки? Q3 .Все, что связано с прослушиванием параметров, когда я передаю параметр.Но технически это не должно быть так, как столбец параметров хорошо организован с равномерно распределенными данными.

1 Ответ

0 голосов
/ 28 апреля 2019

Похоже, у вас возникла проблема с анализом параметров.Я не вижу ваши данные, но часто мы обнаруживаем, что они возникают даже в простых сценариях запросов, когда либо много строк соответствуют результату параметра, и он переворачивается на сканирование, даже если это не должно быть, или возникает какая-то другая проблема с данными, напримермногие значения уникальны, но по некоторому сценарию они решили, что столбец должен иметь 0 в большой части таблицы, бросая все для цикла.Если запрос из кода выполняется медленно, но вы можете выполнить тестовую процедуру из ssms, это довольно большой красный признак того, что что-то в этой строке является вашей проблемой.

Вы правы, что перезапуск SQL сбрасывает все планыкеш или вы можете вручную сбросить все планы, но вы абсолютно не хотите использовать этот метод, чтобы исправить план одной процедуры.Быстрое решение - вы можете выполнить EXEC sp_recompile 'dbo.procname';заставить его сбросить только один план выполнения процедуры и создать новый.Восстановление всех ваших планов, особенно в загруженной базе данных, может вызвать серьезные проблемы с производительностью других процедур, и, конечно, перезапуск может привести к простоям.Это только временно устраняет проблему, когда она возникает, хотя, если вы определили параметр, вызывающий проблемы, я бы рассмотрел дополнительно оптимизацию для неизвестных подсказок, специально предназначенных для обнаруженных проблем с прослушиванием параметров.Но также, возможно, убедитесь, что в вашей среде регулярно ведется хорошее обслуживание индекса, если это вызывает плохие планы, а не механизм sql.

...