Время ожидания запроса истекает при выполнении из Интернета, но очень быстро при выполнении из SSMS

Я пытаюсь отладить источник тайм-аута SQL в поддерживаемом мной веб-приложении. У меня есть исходный код кода C #, поэтому я точно знаю, какой код выполняется. Я отлаживал приложение вплоть до строки, которая выполняет код SQL, время ожидания истекло, и я наблюдаю за выполнением запроса в профилировщике SQL.

Когда этот запрос выполняется из Интернета, он истекает через 30 секунд. Однако, когда я вырезал / вставлял запрос точно так, как представлено в Profiler, помещал его в SSMS и запускал, он возвращался почти мгновенно. Я отследил проблему с тем, что для ARITHABORT установлено значение OFF в соединении, используемом в Интернете (то есть, если я выключу ARITHABORT в сеансе SSMS, он будет работать в течение длительного времени, и если я снова включу его, он запустится очень быстро). Однако, читая описание ARITHABORT, кажется, что это не применимо ... Я просто делаю простой SELECT, и никаких арифметических действий не выполняется вообще ... только одно INNER JOIN с условием WHERE:

Почему ARITHABORT OFF вызывает такое поведение в этом контексте? Есть ли способ изменить настройку ARITHABORT для этого подключения из SSMS? Я использую SQL Server 2008.


person Michael Bray    schedule 11.02.2010    source источник


Ответы (8)


Итак, ваш код C # отправляет специальный SQL-запрос на SQL Server, используя какой метод? Вы рассматривали возможность использования хранимой процедуры? Это, вероятно, обеспечило бы одинаковую производительность (по крайней мере, в движке) независимо от того, кто его называл.

Почему? Параметр ARITHABORT - это одна из вещей, на которую смотрит оптимизатор, когда он определяет, как выполнить ваш запрос (точнее, для сопоставления плана). Возможно, что план в кеше имеет те же настройки, что и SSMS, поэтому он использует кэшированный план, но с противоположной настройкой ваш код C # вызывает перекомпиляцию (или, возможно, вы действительно ПЛОХО plan в кеше), что, безусловно, может снизить производительность во многих случаях.

Если вы уже вызываете хранимую процедуру (вы не публиковали свой запрос, хотя я думаю, что вы это хотели), вы можете попробовать добавить OPTION (RECOMPILE) к ошибочному запросу (или запросам) в хранимой процедуре. Это будет означать, что эти утверждения всегда будут перекомпилироваться, но это может помешать использованию плохого плана, который вы, кажется, сбиваете. Другой вариант - убедиться, что при компиляции хранимой процедуры пакет выполняется с SET ARITHABORT ON.

Наконец, вы, кажется, спрашиваете, как изменить настройку ARITHABORT в SSMS. Я думаю, что вы хотели спросить, как вы можете принудительно настроить ARITHABORT в своем коде. Если вы решите продолжить отправку специального запроса SQL из своего приложения C #, то, конечно, вы можете отправить команду в виде текста, в котором есть несколько операторов, разделенных точкой с запятой, например:

SET ARITHABORT ON; SELECT ...

Дополнительные сведения о том, почему возникает эта проблема, см. В замечательной статье Эрланда Соммарскога:

person Aaron Bertrand    schedule 11.02.2010
comment
Запрос фактически генерируется O / R Mapper (LLBLGen), поэтому я не думаю, что у меня есть большой контроль над ним. Я искал на их форумах ARITHABORT с несколькими ударами, но это заставило меня включить ARITHABORT в качестве настройки по умолчанию на сервере. Это не мое идеальное решение, поэтому я все еще надеюсь понять, почему этот параметр вызвал такое поведение. Я не публиковал запрос, потому что не думаю, что он особенно актуален - я использую ТОЧНЫЙ запрос (вырезать / вставить) в SSMS, который использовался в Интернете, поэтому он должен использовать тот же план, за исключением, как вы говорите для настройки ARITHABORT. Продолжение ..... - person Michael Bray; 12.02.2010
comment
Я также пробовал сбросить кэш планов с помощью DBCC FREEPROCCACHE, но это, похоже, не имело никакого эффекта - Интернет продолжал работать медленно. После того, как я установил параметр ARITHABORT на сервере в положение ON, проблема была удалена из Интернета. Я действительно спрашивал, как я могу повлиять на настройку ДРУГОГО соединения из моего соединения SSMS, но я не думаю, что это возможно. - person Michael Bray; 12.02.2010
comment
Нет комментариев об использовании хранимой процедуры вместо запросов, сгенерированных O / R Mapper? После того, как O / R Mapper сгенерировал запрос, вы, безусловно, можете инкапсулировать этот код в хранимую процедуру, а затем вызвать хранимую процедуру из кода вашего веб-сайта. Это просто дает вам больше контроля над запросом и семантикой, окружающей сам вызов. - person Aaron Bertrand; 12.02.2010
comment
+1 У меня было то же самое. Тайм-аут при запуске через веб-приложение, ‹1 сек при запуске через SMSS. Добавление SET ARITHABORT ON в определение sproc исправило это. Спасибо! PS Что, черт возьми, это значит? - person David; 18.05.2011
comment
@David - Для ясности, ARITHABORT сама по себе не является причиной, и добавление SET ARITHABORT ON к сохраненному определению процедуры не означает, что проблема больше не возникнет. Проблема заключается в обнюхивании параметров. - person Martin Smith; 06.10.2011

Этот ответ включает способ решить эту проблему:

При выполнении следующих команд в базе данных от имени администратора все запросы выполняются должным образом, независимо от параметра ARITHABORT.

 DBCC DROPCLEANBUFFERS
 DBCC FREEPROCCACHE

Обновлять

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

person StriplingWarrior    schedule 06.10.2011
comment
Я не согласен, что связанный ответ лучше, чем уже ответ на этот вопрос. - person Martin Smith; 06.10.2011
comment
@MartinSmith: я изменил свой ответ, чтобы не называть связанный ответ более полным объяснением, но я думаю, что предоставление реального решения, которое устраняет проблему, лучше, чем установка ARITHABORT ON (что на самом деле является кратковременным взломом). Связанный вопрос также указывает на то, что проблема может возникать одинаково хорошо с хранимой процедурой, поэтому простое использование хранимой процедуры также не обязательно исправит ситуацию. - person StriplingWarrior; 06.10.2011
comment
Очистка всего кеша процедур - не самое лучшее решение. ТБХ, это лишь очень дорогостоящее краткосрочное решение. И почему ты тоже бежишь DBCC DROPCLEANBUFFERS? Правильнее всего будет исследовать и исправить проблему прослушивания параметров, которая означает, что два плана выполнения различны. См. http://www.sommarskog.se/query-plan-mysteries.html - person Martin Smith; 06.10.2011
comment
@MartinSmith: Похоже, это интересная статья. Придется перечитать. Не могли бы вы написать ответ на этот вопрос, в котором говорится о сниффинге параметров, о том, как он применяется к запросам, которые не являются частью хранимых процедур, и как исправить запрос, который, похоже, имеет эту проблему? - person StriplingWarrior; 06.10.2011

У меня была эта проблема много раз раньше, но если у вас есть хранимая процедура с той же проблемой, удаление и воссоздание хранимой процедуры решит проблему.

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

Я понимаю, что это может быть не то, что хочет оригинальный плакат, но может помочь кому-то с той же проблемой.

person Novice in.NET    schedule 17.08.2012
comment
Вот хорошая статья, в которой объясняется анализ параметров sommarskog.se/query-plan-mysteries .html # otherreasons - person weilin8; 23.02.2013

При использовании Entity Framework вы должны знать, что параметры запроса для строковых значений по умолчанию отправляются в базу данных как nvarchar, если столбец базы данных для сравнения имеет тип varchar, в зависимости от параметров сортировки план выполнения запроса может потребовать шаг «IMPLICIT CONVERSION», который вызывает полное сканирование. Я мог подтвердить это, посмотрев на мониторинг базы данных в опции дорогих запросов, которая отображает план выполнения.

Наконец, объяснение этого поведения в этой статье: https://www.sqlskills.com/blogs/jonathan/implicit-conversions-that-cause-index-scans/

person edumen    schedule 20.07.2018

Простое использование ARITHABORT не решит проблему, особенно если вы используете параметризованные хранимые процедуры.

Поскольку параметризованные хранимые процедуры могут вызывать «анализ параметров», который использует кэшированный план запроса.

Итак, прежде чем перейти к заключению, пожалуйста, проверьте ссылку ниже.

Слон-и-мышь-или-анализ-параметров-на-сервере-sql

person Prashanth Shivasubramani    schedule 18.06.2020
comment
этот вопрос 10 лет назад, и ваш ответ повторяется. пожалуйста, не повторяйте повторяющийся ответ. этот вопрос не требует ответа, и это отрицательный момент для вашей активности в стеке. я надеюсь, что ты желаешь всего наилучшего - person Amirhossein; 18.06.2020
comment
Спасибо, Амир, дату не проверял! - person Prashanth Shivasubramani; 04.09.2020

У меня была такая же проблема, и она была решена путем выполнения процедуры «С РЕКОМПЛЕКТАМИ». Вы также можете попробовать использовать анализ параметров. Моя проблема была связана с кешем SQL.

person Manmeet    schedule 09.06.2014

Если вы можете изменить свой код, чтобы исправить обнюхивание параметров, оптимизация для неизвестных подсказок - ваш лучший вариант. Если вы не можете изменить свой код, лучшим вариантом будет exec sp_recompile 'name of proc', который заставит только эту сохраненную процедуру получить новый план выполнения. Удаление и воссоздание процесса будет иметь аналогичный эффект, но может вызвать ошибки, если кто-то попытается выполнить процесс, пока он у вас был удален. DBCC FREEPROCCACHE удаляет все ваши кэшированные планы, что может нанести серьезный ущерб вашей системе, в том числе вызвать множество тайм-аутов в производственной среде с интенсивными транзакциями. Настройка arithabort не является решением проблемы, но является полезным инструментом для определения того, является ли анализ параметров проблемой.

person N. Rhoades    schedule 08.01.2016

У меня такая же проблема при попытке вызвать SP из SMSS потребовалось 2 секунды, а из веб-приложения (ASP.NET) потребовалось около 3 минут.

Я пробовал все предложенные решения sp_recompile, DBCC FREEPROCCACHE и DBCC DROPCLEANBUFFERS, но ничего не устранило мою проблему, но когда я попробовал обнюхивать параметры, это помогло и работало нормально.

person Karim Tawfik    schedule 29.03.2017