使用 .NET 适配器的 Sql Server 2005 超时

发布于 2024-11-07 19:29:12 字数 2203 浏览 6 评论 0原文

我正在运行一个从 C# TableAdapter 返回约 30,000 行的查询,并且经常会收到如下错误:

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)

如果我运行相同的查询但返回的行数较少,则不会收到该错误。如果我自己运行与 C# 中的 TableAdapter 在 SSMS 中运行完全相同的查询,则 30,000 行的查询返回正常。

什么可能导致这种情况?

编辑:SSMS 中的查询大约需要 7 秒

I am running a query that returns ~30,000 rows from a C# TableAdapter, and often times I get an error like:

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)

If I run the same query with less rows returned, I won't get the error. And if I run the exact same query that the TableAdapter in C# runs in SSMS myself, the query of 30,000 rows returns fine.

What could cause this?

Edit: The query in SSMS takes ~7 seconds

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

奢望 2024-11-14 19:29:12

您应该延长查询的超时期限才能获得结果。由于结果集很大,查询可能需要一些时间才能完成。在生成结果之前,超时期限很可能已到期,

您可以使用 SQLCommand 的 CommandTimeout 属性来设置到期时间。将其设置为较长的​​时间以进行测试并检查是否得到结果

You should extend the time out period of the query to get results. As the result set is huge, query may take some time to complete. Most Probably the time out period is expiring before results are generated

you can use SQLCommand's CommandTimeout property to set the time to expire. Set it to a large time for testing purpose and check whether you get the results or not

Oo萌小芽oO 2024-11-14 19:29:12

这可能是索引的问题。特别是因为您说查询在 SSMS 中运行而不是在代码中运行。请参阅这篇文章,其中包含更多信息(并且在我看来是一篇很好的文章):

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

This could be a problem with indexes. Especially since you said the query runs in SSMS but not in code. See this article which has more information (and is a good read IMO):

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

独﹏钓一江月 2024-11-14 19:29:12

查询需要多长时间?直接在数据库中运行SQL,速度有多快?如果需要很长时间,可能需要用索引或其他调整方法来转动。

您可以增加超时时间,但为什么返回了 30,000 条记录。如果这不是后台进程,则应将查询设置为分页以一次返回 X 条记录。

如果您绝对需要 30,000 条记录:

使用 DataReader,它比数据适配器速度更快且资源占用更少,请记住它使用仅向前(fire house)方法进行数据检索。

一次以块的形式拉取记录,例如拉取1000,处理,拉取1000,处理....

Net中的超时
调整查询以使其运行速度更快

如果数据不太不稳定,则考虑缓存 30,000 条记录

How long does the query take? Take the SQL and run it directly in the database and how fast is it? It may need to be turned with an index or other tuning method if it is taking a long time.

You can increase the time out but why 30,000 records returned. If this isn't a background process, the query should be set up to be paged to return X records at a time.

If you absolutely need 30,000 records:

User a DataReader, its faster and less resource intensive than a data adapter, just bear in mind it uses a forward only (fire house) approach to data retreival.

Pull records in chunks at a time, for example pull 1000, process, pull 1000, proceess...

Up the timeout in .Net
Tune the Query to make it run faster

Consider caching if the 30,000 records if the data is not too volatile

鹤仙姿 2024-11-14 19:29:12

这是推测性的,但您可能会遇到参数嗅探导致问题的实例。

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

This is speculative but you might be encountering an instance of parameter sniffing causing problems.

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

The quick fix is to add local variables, copy your parameter values to the local variables and then use the local vars in the query. From the article above

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

More info on what is actually happening here:
http://www.sqlpointers.com/2006/11/parameter-sniffing-stored-procedures.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文