ADO.NET вызов хранимой процедуры T-SQL вызывает исключение SqlTimeoutException
у меня есть хранимая процедура T-SQL с подписью
CREATE PROCEDURE MyProc
@recordCount INT OUTPUT
@param1 INT
...
при выполнении непосредственно в Sql Server процедура выполняется менее чем за 5 секунд, возвращая несколько результирующих наборов в общей сложности около 100 строк.
вызов этой процедуры с помощью ADO.NET SqlDataAdapter.Fill метод для заполнения Dataset вызывает SqlTimeoutException на SqlCommand через 3 минуты (указанный интервал).
изменение хранимой процедуры, чтобы она больше не имела выходных данных параметр, и что требуемое выходное значение возвращается как последний результирующий набор, решает проблему, и все это работает менее чем за 5 секунд, как ожидалось.
но почему?
Я не хочу проходить через мою базу кода и изменять все экземпляры этого типа поведения, не понимая, действительно ли я решил проблему.
еще одна вещь, чтобы отметить, что это очевидно только на одном конкретном сервере, который, по общему признанию, имеет больший набор данных, чем другие подобные базы данных, которые мы запускаем. Конечно, не параметр Sql Server?
обновление
шаг в источник framework проблема, по-видимому, заключается в извлечении метаданных. The ConsumeMetaData метод SqlDataReader объект висит неопределенно долго. Однако я запускал тесты в других базах данных и не могу воспроизвести, поэтому при вызове этой процедуры возникает проблема с базой данных ADO.NET-отлично.
ОБНОВЛЕНИЕ II
подтвердили еще происходит, если я изменяю код для использования OleDbDataAdapter С типами поставщиков sqloledb или SQLNCLI. Определенно, это связано со связью.
3 ответов
как только я определил, что это ADO.NET соединение в корне проблемы, это нить привел меня к ответу.
в основном соединения через SQL Server Management Studio (SSMS) по умолчанию установили ARITHABORT ON. ADO.NET связи нет.
задание ARITHABORT OFF и выполнение запроса непосредственно через SSMS дает мне такое же медленное время отклика.
основным отличием при работе с этим параметром или без него является другой запрос план создается для двух вызовов. Когда ARITHABORT был OFF, команда SSMS будет использовать предварительно скомпилированный кэшированный план запроса, который ADO.NET соединение использовалось, и поэтому timeout.
при выполнении следующих команд от имени администратора в базе данных все запросы выполняются, как ожидалось, независимо от ARITHABORT настройка.
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
Я могу только предположить, что скомпилированный план запроса стало поврежден, или неверный.
Я пойду с этим решением (я up-проголосовал ответ) на другой нить
спасибо.
я поправляюсь-да, ты CAN оба - выходной параметр, а также набор строк, возвращаемых. Вы узнаете что-то новое каждый день :-)
что касается того, почему происходит тайм-аут-хм.... трудно сказать. Небольшой образец на скорую руку мне подойдет. Можете ли вы опубликовать сохраненный proc (по крайней мере, соответствующие биты)?
сколько строк мы говорим о том, что возвращаются сюда?
в какой момент в вашем сохраненном proc вы вычисляете количество строк, которые необходимо вернуть в качестве выходного параметра?
Что делать, если вы попытаетесь добавить другой параметр MaxRows на ваш один SProc в качестве теста и сделать SELECT TOP (@MaxRows)....... по вашим данным? Это быстро возвращается?
Марк
короче говоря-я исправил свою проблему, заставив SQL Server использовать наиболее подходящий индекс для ограничения логических чтений lob, когда он не мог понять это самостоятельно.
в лонг -
Я просто столкнулся с этой проблемой и решил ее по-другому, попробовав все другие предложенные ответы. В SSMS запрос выполнялся в ~3s, но время ожидания при вызове из веб-приложения .Net MVC.
вывод статистики IO в SSMS говорил мне, что там было более 195,500,000 lob логических чтений в одной таблице (Таблица 20M-row с кластеризованным индексом columnstore, а также имеет индексы строк, но не имеет столбцов "LOB"). Я заметил из плана выполнения, что основная часть нагрузки (76%) поступала от индексного поиска по одному из индексов строки. Я использовал следующее:
from [table] with (index([clustered columnstore index name]))
в моем запросе, чтобы принудительно использовать кластеризованный индекс columnstore, и мой запрос был уменьшен до 195M, и при вызове SP из веб-приложения теперь, это раунд-триппинг в 1.3 s.
я попробовал перекомпилировать опцию, Установить arithabort on, параметр sniffing, и в конце SQL Server просто не мог понять, какой индекс использовать. Это пограничный случай тоже кстати, и единственный раз, когда мне пришлось заставить индекс в этой базе данных.