У меня есть хранимая процедура, которая безумно истекает каждый раз, когда вызывается из веб-приложения.
Я запустил Sql Profiler и отследил вызовы, которые истекли, и наконец обнаружил следующие вещи:
- При выполнении операторов из MS SQL Management Studio с теми же аргументами (фактически, я скопировал вызов процедуры из трассировки профиля sql и запустил его): он завершается через 5 ~ 6 секунд в среднем.
- Но при вызове из веб-приложения это занимает более 30 секунд (в трассировке), поэтому моя веб-страница к тому времени фактически истекает.
Помимо того, что у моего веб-приложения есть собственный пользователь, все одинаково (та же база данных, соединение, сервер и т. Д.). Я также пробовал запускать запрос непосредственно в студии с пользователем веб-приложения, и это занимает не более 6 сек.
Как узнать, что происходит?
Я предполагаю, что это не имеет ничего общего с тем фактом, что мы используем слои BLL> DAL или адаптеры таблиц, поскольку трассировка ясно показывает, что задержка находится в реальной процедуре. Это все, о чем я могу думать.
ИЗМЕНИТЬ В этой ссылке я узнал, что ADO.NET устанавливает ARITHABORT
значение true - что хорошо в большинстве случаев, но иногда такое случается, и предлагаемое решение - добавить with recompile
параметр в сохраненный процесс. В моем случае это не работает, но я подозреваю, что это очень похоже на это. Кто-нибудь знает, что еще делает ADO.NET или где я могу найти спецификацию?
источник
Ответы:
У меня возникала аналогичная проблема в прошлом, поэтому я очень хочу увидеть решение этого вопроса. Комментарий Аарона Бертрана к OP привел к тому, что время ожидания запроса истекло при выполнении из Интернета, но очень быстро при выполнении из SSMS , и хотя вопрос не является дубликатом, ответ вполне может относиться к вашей ситуации.
По сути, похоже, что SQL Server может иметь поврежденный кэшированный план выполнения. Вы попадаете в плохой план с вашим веб-сервером, но SSMS переходит на другой план, поскольку для флага ARITHABORT существует другой параметр (который в противном случае не повлиял бы на ваш конкретный запрос / сохраненный процесс).
См. Еще один пример, в котором вызов хранимой процедуры T-SQL в ADO.NET вызывает исключение SqlTimeoutException с более полным объяснением и разрешением.
источник
DBCC DROPCLEANBUFFERS
иDBCC FREEPROCCACHE
свое дело! Я предполагаю, что план выполнения был каким-то образом поврежден или не обновлен. Я сомневаюсь, что это постоянное исправление, если оно могло быть повреждено однажды, оно могло бы сделать это снова. Так что я все еще ищу вероятные причины. Поскольку веб-приложение снова заработало, мне не нужно чувствовать давление. Большое спасибо.OPTIMIZE FOR
илиOPTION(Recompile)
запрашивать подсказки по запросам, вызывающим проблемы. В этой статье подробно рассматривается проблема. Если Entity Framework генерирует ваши запросы, этот пост, по- видимому, предоставляет способ добавить подсказку к вашим запросам.Я также сталкивался с тем, что запросы выполнялись медленно из Интернета и быстро в SSMS, и в конце концов я обнаружил, что проблема заключалась в том, что называется анализом параметров.
Для меня исправление заключалось в том, чтобы изменить все параметры, которые используются в sproc, на локальные переменные.
например. изменение:
кому:
Кажется странным, но это устранило мою проблему.
источник
Не для спама, но как надежного полезного решения для других, в нашей системе было много таймаутов.
Я попытался настроить перекомпиляцию хранимой процедуры с помощью,
sp_recompile
и это решило проблему для одного SP.В конечном счете, было большее количество SP, у которых был тайм -аут, многие из которых никогда не делали этого раньше,
DBCC DROPCLEANBUFFERS
иDBBC FREEPROCCACHE
частота тайм-аутов значительно упала - все еще есть отдельные случаи, некоторые из которых, как я подозреваю, требует регенерации плана. какое-то время, а в некоторых случаях SP действительно недостаточно эффективны и нуждаются в переоценке.источник
DBCC DROPCLEANBUFFERS
иDBCC FREEPROCCACHE
не имело значения.Может ли быть, что некоторые другие вызовы БД, сделанные до того, как веб-приложение вызовет SP, сохраняют транзакцию открытой? Это могло быть причиной того, что SP будет ждать при вызове веб-приложением. Я предлагаю изолировать вызов в веб-приложении (поместить его на новую страницу), чтобы убедиться, что некоторые предыдущие действия в веб-приложении вызывают эту проблему.
источник
Простая перекомпиляция хранимой процедуры (табличная функция в моем случае) сработала для меня
источник
как @Zane сказал, что это может быть из-за обнюхивания параметров. Я испытал такое же поведение, и я взглянул на план выполнения процедуры и все операторы sp в строке (скопировал все операторы из процедуры, объявил параметры как переменные и присвоил переменной те же значения, что и параметры были). Однако план казни выглядел совершенно иначе. Выполнение sp заняло 3-4 секунды, и сразу же были возвращены следующие подряд операторы с точно такими же значениями.
После некоторого поиска в Google я нашел интересную статью об этом поведении: медленно в приложении, быстро в SSMS?
Проблема заключалась в том, что у меня были параметры, которые можно было оставить нулевыми, и если бы они были переданы как нулевые, они были бы инициализированы значением по умолчанию.
После того, как я изменил его на
это снова сработало как шарм.
источник