Тайм-ауты SQL Server 2005 с адаптерами .NET - PullRequest
0 голосов
/ 17 мая 2011

Я выполняю запрос, который возвращает ~ 30 000 строк из C # TableAdapter, и часто я получаю сообщение об ошибке типа:

Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding. 

at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)\r\n   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)\r\n   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)

Если я выполню тот же запрос с меньшим количеством возвращенных строк, я не получу ошибку. И если я выполняю точно такой же запрос, какой TableAdapter в C # выполняет сам в SSMS, запрос из 30000 строк возвращает нормально.

Что может вызвать это?

Редактировать: запрос в SSMS занимает ~ 7 секунд

Ответы [ 4 ]

3 голосов
/ 17 мая 2011

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

вы можете использовать свойство CommandTimeout SQLCommand, чтобы установить время истечения. Установите большое время для тестирования и проверьте, получаете ли вы результаты или нет

0 голосов
/ 17 мая 2011

Это предположительно, но вы можете столкнуться с экземпляром сниффинга параметров, вызывающим проблемы.

http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/

Быстрое решение - добавить локальные переменные, скопировать значения параметров в локальные переменные и затем использовать локальные переменные в запросе. Из статьи выше

CREATE PROCEDURE MyProcedure
     @UserName nvarchar(20)
 AS

 BEGIN
     DECLARE @myUserName nvarchar(20)
     SET @myUserName = @UserName
     -- Insert statements for procedure here
     SELECT DisplayName, FirstName, LastName 
     FROM dbo.User
     WHERE UserName = @myUserName

END

Подробнее о том, что на самом деле происходит здесь: http://www.sqlpointers.com/2006/11/parameter-sniffing-stored-procedures.html

0 голосов
/ 17 мая 2011

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

Вы можете увеличить время ожидания, но почему возвращается 30 000 записей.Если это не фоновый процесс, запрос должен быть настроен на постраничное возвращение X записей одновременно.

Если вам абсолютно необходимо 30 000 записей:

Пользователь DataReader, более быстрый и менее ресурсоемкий, чем адаптер данных, просто имейте в виду, что он использует только прямой (пожарный) подход к даннымRetreival.

Одновременное извлечение записей по частям, например, извлечение 1000, обработка, извлечение 1000, выполнение ...

Увеличьте время ожидания в .Net Настройте запрос, чтобы он работал быстрее

Рассмотрите возможность кэширования, если 30 000 записей, если данные не слишком изменчивы

0 голосов
/ 17 мая 2011

Это может быть проблема с индексами. Тем более, что вы сказали, что запрос выполняется в SSMS, но не в коде. См. Эту статью, которая имеет больше информации (и является хорошим прочитанным IMO):

http://www.sommarskog.se/query-plan-mysteries.html

...