Время ожидания запроса из веб-приложения, но отлично работает из студии управления

Это вопрос, который я задал на другом форуме, на который были даны неплохие ответы, но я хотел узнать, есть ли у кого-нибудь больше понимания.

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

В моем конкретном случае использовались ASP.NET 2.0 и Sql Server 2005, но я думаю, что проблема может относиться к любой системе СУБД.

Ответов (8)

Решение

Это то, что я узнал из своих исследований.

.NET отправляет параметры подключения, которые не совпадают с теми, которые вы получаете при входе в студию управления. Вот что вы увидите, если понюхаете соединение с Sql Profiler:

-- network protocol: TCP/IP  
set quoted_identifier off  
set arithabort off  
set numeric_roundabort off  
set ansi_warnings on  
set ansi_padding on  
set ansi_nulls off  
set concat_null_yields_null on  
set cursor_close_on_commit off  
set implicit_transactions off  
set language us_english  
set dateformat mdy  
set datefirst 7  
set transaction isolation level read committed  

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

В этом случае я попробовал каждую настройку индивидуально после отключения и повторного подключения и обнаружил, что изменение arithabort с выключенного на on уменьшило проблемный запрос с 90 секунд до 1 секунды.

Наиболее вероятное объяснение связано с анализом параметров, который представляет собой методику, которую Sql Server использует для выбора того, что, по его мнению, является наиболее эффективным планом запроса. Когда вы меняете одну из настроек подключения, оптимизатор запросов может выбрать другой план, и в этом случае он явно выбрал плохой.

Но я не совсем уверен в этом. Я попытался сравнить фактические планы запросов после изменения этого параметра, но мне еще предстоит увидеть какие-либо изменения в различиях.

Есть ли что-то еще в настройке arithabort, из-за чего в некоторых случаях запрос может выполняться медленно?

Решение казалось простым: просто поместите set arithabort в начало хранимой процедуры. Но это может привести к противоположной проблеме: изменить параметры запроса, и внезапно он будет работать быстрее с «выключенным», чем с «включенным».

В настоящее время я запускаю процедуру «с перекомпиляцией», чтобы каждый раз обновлять план. Это нормально для этого конкретного отчета, так как может потребоваться секунда для перекомпиляции, и это не слишком заметно для отчета, для возврата которого требуется 1-10 секунд (это монстр).

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

сначала проверьте это на промежуточном поле, измените его на уровне сервера для sql server

объявить @option int

установить параметры @option = @@ | 64

exec sp_configure 'параметры пользователя', @option

ПЕРЕКОНФИГУРИРОВАТЬ

У нас была такая же проблема, и вот что мы узнали.

размер журнала нашей базы данных сохранялся по умолчанию (814 МБ), а автоматический рост составлял 10%. На сервере также был сохранен максимальный объем памяти сервера по умолчанию (2147483647 МБ).

Когда наш журнал заполнился и его нужно было увеличить, он использовал всю память сервера, и для запуска кода не осталось ничего, поэтому время ожидания истекло. В итоге мы установили начальный размер файла журнала базы данных равным 1 МБ, а максимальный размер памяти сервера - 2048 МБ. Это мгновенно устранило нашу проблему. Конечно, вы можете изменить эти два свойства в соответствии с вашими потребностями, но это идея для тех, кто сталкивается с проблемой тайм-аута при выполнении хранимой процедуры с помощью кода, но она выполняется очень быстро в SSMS, и приведенные выше решения не помогают.

Попробуйте изменить значение тайм-аута SelectCommand:

DataAdapter.SelectCommand.CommandTimeout = 120;

Вы уже включили трассировку ASP.NET? У меня был случай, когда проблема заключалась не в самой хранимой процедуре SQL, а в том, что процедура вернула 5000 строк, а приложение пыталось создать ListItems с привязкой к данным с этими 5000 элементами, которые вызывали проблему.

Вы можете посмотреть время выполнения между функциями веб-приложения, а также через трассировку, чтобы отслеживать вещи.

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

Та же проблема, что и у меня со службами отчетов SQL. Попробуйте проверить тип переменных, я отправлял в SQL переменные другого типа, например, отправлял varchar на место, где он должен быть целым числом, или что-то в этом роде. После того, как я синхронизировал типы переменных в Reporting Service и в хранимой процедуре на SQL, я решил проблему.

У меня были похожие проблемы. Попробуйте установить опцию «WITH RECOMPILE» в sproc create, чтобы заставить систему пересчитывать план выполнения каждый раз, когда он вызывается. Иногда процессор запросов запутывается в сложных хранимых процедурах с большим количеством операторов ветвления или case и просто вытаскивает действительно неоптимальный план выполнения. Если это, кажется, «решит» проблему, вам, вероятно, потребуется проверить актуальность статистики и / или сломать sproc.

Вы также можете подтвердить это, профилировав sproc. Когда вы выполняете его из SQL Managment Studio, как сравнивается ввод-вывод при его профилировании из приложения ASP.NET. Если их очень много, это просто подтверждает, что его план выполнения плохой.