Времена запроса при выполнении от сети, но сверхбыстрый при выполнении от SSMS

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

Когда этот запрос выполняется от сети, он испытывает таймаут после 30 секунд. Однако, когда я сократил/вставил запрос точно, как представлено в Профилировщике, и я поместил его в SSMS и выполнил его, он возвращается почти немедленно. Я проследил проблему до ARITHABORT, устанавливаемого на ПРОЧЬ в соединении, которое сеть использует (то есть, если я выключаю ARITHABORT на сессии SSMS, это работает в течение долгого времени, и если я снова включаю его затем, это работает очень быстро). Однако читая описание ARITHABORT, это, кажется, не применяется... Я только делаю простой ВЫБОР, и нет НИКАКОЙ арифметики, выполняемой вообще.. просто единственное ВНУТРЕННЕЕ ОБЪЕДИНЕНИЕ с, ГДЕ условие:

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

41
задан Aaron Bertrand 31 July 2018 в 17:08
поделиться

1 ответ

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

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

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

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

SET ARITHABORT ON; SELECT ...

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

39
ответ дан 27 November 2019 в 00:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: