Это вопрос, который я задал на другом форуме, который получил несколько достойных ответов, но я хотел посмотреть, есть ли у кого-нибудь здесь более глубокие идеи.
Проблема в том, что одна из ваших страниц в веб-приложении блокируется по времени, когда он попадает на вызов хранимой процедуры, поэтому вы используете Sql Profiler или журналы трассировки приложения, чтобы найти запрос, и вставляете его в Management Studio для расчета наша почему работает медленно Но вы запускаете его оттуда, и он просто горит, возвращаясь менее чем за секунду каждый раз.
В моем конкретном случае использовались ASP.NET 2.0 и Sql Server 2005, но я думаю, что проблема может относиться к любой системе СУБД.
Попробуйте изменить значение времени ожидания SelectCommand:
DataAdapter.SelectCommand.CommandTimeout = 120;
Это то, что я узнал так далеко от моих исследований.
.NET отправляет параметры подключения, которые не совпадают с настройками, которые вы получаете при входе в Management Studio. Вот что вы увидите, если понюхаете соединение с 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 секунд (это монстр).
Но это не вариант для других запросов, которые выполняются гораздо чаще и должны возвращаться как можно быстрее, всего за несколько миллисекунд.
сначала проверьте это в промежуточном окне, измените его на уровне сервера для сервера sql
объявить @option int
установить @option = @@ options | 64
exec sp_configure 'user options', @option
RECONFIGURE
Вы уже включили трассировку ASP.NET? У меня был случай, когда проблема заключалась не в самой хранимой процедуре SQL, а в том, что процедура возвращала 5000 строк, а приложение пыталось создать элементы ListItems с данными из этих 5000 элементов, что вызывало проблему.
Вы можете посмотреть время выполнения между функциями веб-приложения, а также проследить трассировку.
Вы можете попробовать использовать команду sp_who2, чтобы увидеть, что делает рассматриваемый процесс. Это покажет вам, заблокирован ли он другим процессом или использует слишком много процессорного времени и / или времени.
Та же проблема, что у меня была с службами отчетов SQL. Попробуйте проверить тип переменных, я отправлял переменные другого типа в SQL, например, отправлял varchar туда, где он должен быть целым числом, или что-то в этом роде. После того, как я синхронизировал типы переменных в Reporting Service и в хранимых процедурах на SQL, я решил проблему.
У меня были похожие проблемы. Попробуйте установить параметр with WITH RECOMPILE в sproc create, чтобы заставить систему пересчитывать план выполнения при каждом его вызове. Иногда процессор запросов запутывается в сложных хранимых процедурах с множеством ветвлений или операторов case и просто использует действительно неоптимальный план выполнения. Если кажется, что это «решает» проблему, вам, вероятно, потребуется проверить актуальность статистики и / или устранить проблему.
Вы также можете подтвердить это, профилировав sproc. Когда вы выполняете его из SQL Managment Studio, как сравнивается IO с тем, когда вы профилируете его из приложения ASP.NET. Если их очень много, он просто усиливает, что это тянет плохой план выполнения.
У нас была та же проблема, и вот что мы узнали.
размер журнала нашей базы данных оставался по умолчанию (814 МБ), а автоматический рост составил 10%. На сервере максимальная память сервера также сохранялась по умолчанию (2147483647 МБ).
Когда наш журнал заполнился и его нужно было увеличить, он использовал всю память сервера, и для запуска кода не осталось ничего, поэтому время истекло. В итоге мы установили начальный размер файла журнала базы данных равным 1 МБ, а максимальный объем памяти сервера - 2048 МБ. Это сразу решило нашу проблему. Конечно, вы можете изменить эти два свойства в соответствии с вашими потребностями, но это идея для тех, кто сталкивается с проблемой тайм-аута при выполнении хранимой процедуры с помощью кода, но она работает очень быстро в SSMS, и приведенные выше решения не помогают.