Запрос SQL Server выполняется медленнее ADO.NET чем в SSMS

У меня есть запрос с веб-сайта, который занимает 15-30 секунд, пока выполняется тот же запрос .5 секунд от SQL Server Management studio. Я не вижу никаких проблем с блокировкой с помощью SQL Profiler, и я не могу воспроизвести задержку вручную из SSMS. Неделю назад я отсоединил и снова подключил базу данных, которая, казалось, чудесным образом исправила проблему. Сегодня, когда проблема снова подняла свою уродливую голову, я попытался просто перестроить индексы. Это также исправило проблему. Однако, я не думаю, что это обязательно проблема с индексом, так как индексы не будут автоматически перестраиваться на простом отсоединении / присоединении, насколько мне известно.

есть идеи, что может быть причиной задержки? Моя первая мысль заключалась в том, что, возможно, какой-то параметр, нюхающий вызываемую хранимую процедуру (сказал, что хранимый proc запускает CTE, если это имеет значение), вызывает плохой план запроса, который объяснил бы прерывистый характер проблемы. Так как снятие / установка и перестроения индекса теоретически должен аннулировать кэшированный план запроса, это имеет смысл, но я не уверен, как это проверить. Кроме того, почему один и тот же запрос (скопированный непосредственно из SQL Profiler с точно такими же параметрами) не будет иметь такой же задержки при запуске вручную через SSMS?

какие мысли?

5 ответов


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

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

лучше всего попытаться захватить плохой план выполнения. класс событий XML Showplan событие профилировщика ваш друг, вы можете получить план ADO.Net звоните. Это очень тяжелое событие, поэтому вы должны прикрепить профилировщик и захватить его только тогда, когда проблема проявляется, за короткий сеанс.

статистика ввода-вывода запроса также может помочь. RPC:завершено и SQL: пакет завершен события оба включают чтения и Записывает, чтобы вы могли сравнить количество логических операций ввода-вывода, выполняемых ADO.Net вызов против SSMS one. Большая разница (для одного и того же запроса и параметров) указывает на разные планы.sys.dm_exec_query_stats это еще один путь расследования. Вы можете найти свой план(ы) запроса там и проверить статистику выполнения.

все это должно помочь установить с уверенностью, если проблема-плохой план или что-то еще, для начала.


Я знаю, что я взвешиваю эту тему очень поздно, но я хотел опубликовать решение, которое я нашел при наличии аналогичной проблемы. Короче говоря, добавление команды SET ARITHABORT ON в начале моих процедур привело производительность запросов веб-сайта в соответствие с производительностью средств SQL Server. Этот параметр обычно устанавливается в соединении при выполнении запроса из QA или SSMS (этот параметр можно изменить, но он используется по умолчанию).

в моем случае, у меня было около 15 разных хранимые процессы, выполняющие математические агрегаты (суммы, подсчеты, AVGs, STDEVs) по довольно значительному набору данных (от 10 до 100 тысяч строк) - Добавление параметра SET ARITHABORT on переместило их все от запуска в 3-5 секунд каждый до 20-30ms.

Итак, надеюсь, это поможет кому-то еще.


У меня была такая же проблема. Единственный способ исправить это-установить ARITHABORT. но, к сожалению,когда это происходит снова, я должен установить ARITHABORT.

Я понятия не имею, что ARITHABORT имеет к этому отношение, но он работает, у меня эта проблема уже более 2 лет без решения. Базы данных, с которыми я работаю, составляют более 300 ГБ, поэтому, возможно, это проблема размера...

ближе всего к решению этой проблемы я получил от более раннего должность Google группы в должности

Дайте мне знать, если вам удалось полностью решить эту проблему, так как это очень неприятно!


возможно ли, что ваш ADO.NET запрос выполняется после того, как система была занята другими вещами, так что необходимые данные больше не находятся в ОЗУ? И когда вы тестируете на SSMS, это так?

вы можете проверить это, выполнив следующие две команды из SSMS перед запуском запроса:

CHECKPOINT
DBCC DROPCLEANBUFFERS

Если это заставляет запрос SSMS работать медленно, то есть некоторые трюки, которые вы можете играть на ADO.NET сторона, чтобы помочь ему работать быстрее.


у Саймона Сабина есть отличный сеанс "когда план запроса идет не так" (http://sqlbits.com/Sessions/Event5/When_a_query_plan_goes_wrong), который обсуждает, как решить эту проблему в procs, используя различные подсказки "оптимизировать для" и такие, чтобы помочь proc генерировать согласованный план и не использовать нюхание параметров по умолчанию.

однако у меня есть проблема с и специальным запросом (не в proc), где план SSMS и план ASP точно такие же-кластеризованные сканирование индекса / таблицы-и все же запрос ASP занимает 3+ минуты вместо 1 секунды. (В этом случае сканирование таблицы является достойным ответом на получение результатов.)

кто-нибудь объяснить?