Sql server ADO.NET调用T-SQL存储过程会导致SqlTimeoutException

Sql server ADO.NET调用T-SQL存储过程会导致SqlTimeoutException,sql-server,tsql,ado.net,timeout,output-parameter,Sql Server,Tsql,Ado.net,Timeout,Output Parameter,我有一个带有签名的T-SQL存储过程 CREATE PROCEDURE MyProc @recordCount INT OUTPUT @param1 INT ... 直接在Sql Server中执行时,该过程在5秒内运行,返回的结果集总计约为100行 使用ADO.NETSqlDataAdapter.Fill方法调用此过程以填充数据集会导致SqlCommand在3分钟(指定的超时间隔)后出现SqlTimeoutException 更改存储过程,使其不再具有输出参数,并将所需的输出值作为最后一个结

我有一个带有签名的T-SQL存储过程

CREATE PROCEDURE MyProc
@recordCount INT OUTPUT
@param1 INT
...
直接在Sql Server中执行时,该过程在5秒内运行,返回的结果集总计约为100行

使用ADO.NET
SqlDataAdapter.Fill
方法调用此过程以填充
数据集
会导致
SqlCommand
在3分钟(指定的超时间隔)后出现
SqlTimeoutException

更改存储过程,使其不再具有输出参数,并将所需的输出值作为最后一个结果集返回,这样就解决了问题,整个过程按预期在5秒内运行

但是为什么呢

我不想在不了解我是否真的解决了问题的情况下,浏览我的代码库并修改此类行为的所有实例

另一件需要注意的事情是,这只在一个特定的服务器上明显可见,无可否认,该服务器的数据集比我们运行的其他类似数据库的数据集要大。肯定不是Sql Server设置

更新

进入框架源代码后,问题似乎出现在元数据检索中。
SqlDataReader
对象的
consumerata
方法无限期挂起。但是,我在其他数据库上运行了测试,无法复制,因此,当通过ADO.NET调用此过程时,这是一个特定于数据库的问题。。。太好了

更新II


已确认如果我将代码更改为将
OleDbDataAdapter
与SQLOLEDB或SQLNCLI提供程序类型一起使用,问题仍然会发生。肯定与连接有关。

我已更正-是的,可以同时拥有两个-一个输出参数和一组返回的行。你每天都会学到新东西:-)

至于为什么会发生超时-嗯。。。。很难说。一个快速的小样本对我来说很好。你能发布你的存储过程(至少是相关的部分)吗

我们谈论的是多少行,返回到这里

在存储过程的什么时候计算需要作为输出参数返回的行数

如果您尝试将另一个参数
MaxRows
添加到一个存储过程中作为测试,并对数据执行
SELECT TOP(@MaxRows)…
,该怎么办?这会很快恢复吗


Marc

一旦我确定问题的根源是ADO.NET连接,这就让我找到了答案

默认情况下,通过SQLServerManagementStudio(SSMS)的连接基本上已将
ARITHABORT设置为ON
。ADO.NET连接不可用

设置
ARITHABORT-OFF
并直接通过SSMS执行查询会给我同样的慢响应时间

使用或不使用此设置运行时的主要区别是为两个调用创建了不同的查询计划。当
ARITHABORT
OFF
时,SSMS命令将使用ADO.NET连接使用的预编译缓存查询计划,因此超时

通过以管理员身份在数据库上运行以下命令,所有查询都会按预期运行,而与
ARITHABORT
设置无关

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
我只能假设已编译的查询计划已损坏或无效

另一方面,我会选择这个作为解决方案(我已经投票支持了答案)


谢谢。

简言之,我通过强制SQL Server使用最合适的索引来限制lob逻辑读取,解决了我的问题

长远而言—

在尝试了所有其他建议的答案后,我遇到了这个问题,并以不同的方式解决了它。在SSMS中,查询运行时间约为3秒,但从.Net MVC web应用程序调用时超时

SSMS中的统计IO输出告诉我,一个表上有超过195500000个lob逻辑读取(具有聚集列存储索引的20M行表,也有行索引,但没有“lob”列)。我从执行计划中注意到,大部分负载(76%)来自一个行索引上的索引查找。我使用了以下方法:

from [table] with (index([clustered columnstore index name]))

在我的查询中,强制使用聚集的columnstore索引,我的查询被缩减为:如果使用datareader,这是否有效?当sql profiler卡在sqldataadapter.fill中时,您看过它了吗?SqlDataReader也是这样。也对其进行了分析。在交互方面,我看到它的持续时间不到5秒,通过ADO.NET调用的调用与分析器显示的调用完全相同,它的持续时间为超时时间(180000毫秒)。Fill方法挂起并保持连接,直到连接超时。你确定这一点吗?我可以发誓,我以前在结果集中使用了输出参数,正如我所说,我以交互方式运行没有问题。@marc_如问题所述,大约返回了100行(即最小值)。正如问题所述,这一切都在几秒钟内以交互方式工作。只有通过ADO.NET调用时,我们才能得到问题。除非通过ADO.NET调用该过程来填充数据集,否则该过程运行正常。我正在逐步浏览SqlDataAdapter.Fill的源代码,查看它挂起的位置/原因。谢谢。警告这个答案只是一个非常短期的解决方案,完全不必要的残酷
DBCC DROPCLEANBUFFERS
将从缓存中删除大部分数据页,并且没有任何效果
DBCC FREEPROCCACHE
将刷新整个过程缓存,只为了删除一个有问题的计划!无法保证该问题在未来某个阶段不会再次发生。问题是参数嗅探。马丁史密斯:我已经看完了那篇文章,真的很难找到它。您能否解释一下,在不运行这两行代码的情况下,人们可以做些什么来解决这个问题,以及人们可以做些什么来避免将来发生这种情况?@StriplingWarrior这是另一篇好文章