Время запроса из веб-приложения истекло, но из студии управления он работает нормально
-
08-06-2019 - |
Вопрос
Это вопрос, который я задал на другом форуме, на который получил несколько достойных ответов, но мне хотелось узнать, есть ли у кого-нибудь здесь больше понимания.
Проблема в том, что у вас есть тайм-аут одной из ваших страниц в веб-приложении, когда она доходит до вызова хранимой процедуры, поэтому вы используете Sql Profiler или журналы трассировки вашего приложения, чтобы найти запрос, и вставляете его в студию управления, чтобы выяснить почему он работает медленно.Но вы запускаете его оттуда, и он просто летит вперед, каждый раз возвращаясь менее чем за секунду.
В моем конкретном случае использовалось ASP.NET 2.0 и Sql Server 2005, но я думаю, что проблема может возникнуть в любой системе РСУБД.
Решение
Это то, что я узнал в результате своего исследования.
.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 с выключенного на включенное сокращает время запроса проблемы с 90 секунд до 1 секунды.
Наиболее вероятное объяснение связано с анализом параметров — методом, который Sql Server использует для выбора наиболее эффективного плана запроса.Когда вы меняете одну из настроек подключения, оптимизатор запросов может выбрать другой план, и в данном случае он, видимо, выбрал плохой.
Но я в этом не до конца уверен.Я попытался сравнить фактические планы запросов после изменения этого параметра, но мне еще не удалось увидеть какие-либо изменения в различиях.
Есть ли в настройке arithabort что-то еще, что в некоторых случаях может привести к медленному выполнению запроса?
Решение казалось простым:Просто поместите set arithabort в начало хранимой процедуры.Но это может привести к противоположной проблеме:измените параметры запроса, и внезапно он будет работать быстрее с «выключено», чем с «включено».
На данный момент я запускаю процедуру «с перекомпиляцией», чтобы убедиться, что план каждый раз перегенерируется.Это нормально для этого конкретного отчета, поскольку перекомпиляция занимает, возможно, секунду, и это не слишком заметно в отчете, возврат которого занимает 1-10 секунд (это монстр).
Но это не вариант для других запросов, которые выполняются гораздо чаще и требуют возврата как можно быстрее, всего за несколько миллисекунд.
Другие советы
У меня были подобные проблемы.Попробуйте установить параметр with «WITH RECOMPILE» в процедуре создания, чтобы заставить систему пересчитывать план выполнения при каждом ее вызове.Иногда процессор запросов путается в сложных хранимых процедурах с множеством операторов ветвления или регистра и просто выдает действительно неоптимальный план выполнения.Если кажется, что это «решает» проблему, вам, вероятно, потребуется проверить актуальность статистики и/или разобрать процедуру.
Вы также можете подтвердить это, профилировав sproc.Когда вы выполняете его из SQL Managment Studio, каковы результаты ввода-вывода по сравнению с тем, когда вы профилируете его из приложения ASP.NET.Если их очень много, это только подтверждает, что у вас плохой план выполнения.
Вы уже включили трассировку ASP.NET?У меня был случай, когда проблема заключалась не в самой хранимой процедуре SQL, а в том, что процедура возвращала 5000 строк, и приложение пыталось создать ListItems с привязкой к данным с этими 5000 элементами, что вызывало проблему.
Вы также можете просмотреть время выполнения между функциями веб-приложения с помощью трассировки, чтобы отслеживать ситуацию.
сначала проверьте это на промежуточном блоке, измените его на уровне сервера для сервера sql
объявить @option int
SET @Option = @@ Options | 64
exec sp_configure 'пользовательские параметры', @option
ПЕРЕКОНФИГУРИРОВАНИЕ
Та же проблема, что и у меня была со службами отчетов SQL.Попробуйте проверить тип переменных, я отправлял различные типы переменных в SQL, например, отправлять Varchar на месте, где он должен быть целым числом, или что -то в этом роде.После того как я синхронизировал типы переменных в службе отчетов и в хранимой процедуре SQL, я решил проблему.
Вы можете попробовать использовать команду sp_who2, чтобы увидеть, что делает рассматриваемый процесс.Это покажет вам, заблокирован ли он другим процессом или используется ли чрезмерное количество процессорного времени и/или времени ввода-вывода.
У нас была та же проблема, и вот что мы выяснили.
Размер журнала нашей базы данных сохранялся по умолчанию (814 МБ), а автоматический рост составлял 10%.На сервере максимальная память сервера также была сохранена по умолчанию (2147483647 МБ).
Когда наш журнал был заполнен и нуждался в увеличении, он использовал всю память сервера, и для запуска кода не оставалось ничего, поэтому время ожидания истекло.В итоге мы установили начальный размер файла журнала базы данных на 1 МБ и максимальную память сервера на 2048 МБ.Это мгновенно решило нашу проблему.Конечно, вы можете изменить эти два свойства в соответствии со своими потребностями, но это идея для тех, кто сталкивается с проблемой тайм-аута при выполнении хранимой процедуры с помощью кода, но в SSMS она выполняется очень быстро, и приведенные выше решения не помогают.
Попробуйте изменить значение тайм-аута SelectCommand:
DataAdapter.SelectCommand.CommandTimeout = 120;