Очень медленная хранимая процедура T-SQL ускорилась за счет удаления и воссоздания - PullRequest
2 голосов
/ 31 июля 2011

У меня есть простая хранимая процедура в T-SQL, которая мгновенно запускается из SQL Server Management Studio и имеет простой план выполнения.Он используется в веб-интерфейсе C #, где он обычно быстрый, но иногда кажется, что он попадает в состояние, в котором он находится и время ожидания истекло.Затем он делает это последовательно с любого веб-сервера.Единственный способ исправить это, что я нашел, это сбросить и воссоздать его.Это происходит только с одной хранимой процедурой, из пары сотен подобных процедур, которые используются в приложении.

Я ищу ответ, который лучше, чем создание службы для проверки каждые n минут исброс и воссоздание по таймауту.

Ответы [ 6 ]

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

Как указывалось в других ответах, причин может быть много, начиная от плана выполнения, заканчивая действительным кодом SP или чем-то еще.Однако в моем прошлом опыте я столкнулся с подобной проблемой из-за «перехвата параметров».Google для этого и посмотрите, это могло бы помочь.По сути, вы должны использовать локальные переменные в вашем SP вместо параметров, переданных в.

2 голосов
/ 06 января 2012

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

Я работал над проблемой, когда хранимый процесс в большинстве случаев занимал бы 10 секунд, но время от времени 3-4 минуты. Немного покопавшись, я нашел шаблон в номере:
Это хранимый процесс, который принимает дату начала и дату окончания, и если я запускаю его для данных за год (что обычно делают люди), он запускается за 10 секунд. Однако, когда кэш плана запросов был очищен, и если кто-то запускал его в течение дня (необычный вариант использования), все дальнейшие вызовы для диапазона в 1 год будут занимать 3-4 минуты, пока я не выполню DBCC FREEPROCCACHE

Следующие 2 вещи позволили решить проблему

  1. Моим первым подозреваемым был нюхающий параметр. Исправили это немедленно, используя подход с использованием локальной переменной. Однако это повысило производительность только на небольшой процент (
  2. В подходе «цепляйся за соломинку» я изменил переменные таблицы, которые исходный разработчик использовал в этом хранимом процессе, на временные таблицы. Это было то, что наконец решило проблему. Теперь, когда я знаю, что это была проблема, я читаю онлайн и наткнулся на несколько ссылок, таких как http://www.sqlbadpractices.com/using-table-variable-for-large-table-vs-temporary-table/ которые, кажется, соответствуют проблеме, которую я вижу.

Удачного кодирования !!

2 голосов
/ 31 июля 2011

Запустите SQL Profiler и запускайте его с веб-сайта, пока это не произойдет снова.Когда он делает паузу / тайм-аут, проверьте, что происходит на самом сервере SQL.

Здесь много возможностей в зависимости от того, что на самом деле делает s'proc.Например, если он вставляет записи, у вас могут возникнуть проблемы, когда серверу баз данных необходимо расширить базу данных и / или размер файла журнала, чтобы принимать новые данные.Если это происходит в файле журнала, и у вас медленные диски или они превышают макс. Места на диске, это может привести к тайм-ауту.

Если это выбор, то эти таблицы могут быть заблокированы на некоторое время из-запроисходят другие вставки ... Или это может быть повторное использование неверного плана выполнения.

Танец отбрасывания / воссоздания может только отложить выполнение до такой степени, что SQL-сервер может нагнать его или вызватьперекомпилировать.

1 голос
/ 31 июля 2011

Трудно сказать наверняка, не увидев код SP.
Некоторые предложения.
Сервер SQL по умолчанию повторно использует план выполнения хранимой процедуры.План генерируется при первом исполнении.Это может вызвать проблемы.Например, впервые вы предоставляете входные данные с очень высокой избирательностью, а SQL Server создает план с учетом этого.В следующий раз вы передадите ввод с низкой избирательностью, но SP повторно использует старый план, вызывая очень медленное выполнение.
Наличие разных путей выполнения в SP вызывает ту же проблему.
Попробуйте создать эту процедуру WITH RECOMPILE, чтобы предотвратить кэширование.
Надеюсь, это поможет.

1 голос
/ 31 июля 2011

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

Скорее всего, это вызвано вашим планом выполнения в кэше.

Попробуйте использовать DBCC FREEPROCCACHE для очистки кеша в следующий раз, когда это произойдет.Подробнее здесь http://msdn.microsoft.com/en-us/library/ms174283.aspx

Даже это реактивный шаг - он на самом деле не решает проблему.

Я предлагаю вам выполнить процедуру в SSMS и проверить фактический план выполнения и рисунокиз того, что вызывает задержку.(в меню перейдите к [View] и затем [Включить фактический план выполнения])

0 голосов
/ 31 июля 2011

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

Я не эксперт по MS SQL, но я бы не сталудивитесь, что он ведет себя аналогично Oracle, когда две параллельные транзакции пытаются удалить одну и ту же строку: транзакция, которая первой достигает удаления, блокирует строку, а вторая транзакция затем блокируется до тех пор, пока первая транзакция не выполнит фиксацию или откат.Если это было предпринято в вашей процедуре, это может выглядеть как «зависание» (до завершения транзакции «блокировки»).

Есть ли у вас какие-либо длительные транзакции, которые могут заблокировать строки, к которым обращается ваша процедура?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...