sql – Linq存储过程超时但SSMS快速

前端之家收集整理的这篇文章主要介绍了sql – Linq存储过程超时但SSMS快速前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个存储过程,我使用 LinqTosql调用.我根本没做任何特别的事,例如
MyDataContext db = new MyDataContext()

var results = db.storedProcedure(param1,param2,param3)

// Do stuff

当我使用完全相同的参数运行存储过程时,我得到2到6秒之间的结果.该数据库是一个远程数据库.

但是,当我运行存储过程时(经过调试……)275秒!在正常情况下,这会产生以下异常:

[Win32Exception (0x80004005): The wait operation timed out]

[sqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.]
System.Data.sqlClient.sqlConnection.OnError(sqlException exception,Boolean breakConnection,Action1 wrapCloseInAction) +1753346
System.Data.sqlClient.sqlInternalConnection.OnError(sqlException exception,Action
1 wrapCloseInAction) +5295154
System.Data.sqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncClose) +242
System.Data.sqlClient.TdsParser.TryRun(RunBehavior runBehavior,sqlCommand cmdHandler,sqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean& dataReady) +1682
System.Data.sqlClient.sqlDataReader.TryConsumeMetaData() +59
System.Data.sqlClient.sqlDataReader.get_MetaData() +90
System.Data.sqlClient.sqlCommand.FinishExecuteReader(sqlDataReader ds,RunBehavior runBehavior,String resetOptionsString) +365
System.Data.sqlClient.sqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,Boolean returnStream,Boolean async,Int32 timeout,Task& task,Boolean asyncWrite) +1325
System.Data.sqlClient.sqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,String method,TaskCompletionSource`1 completion,Boolean asyncWrite) +175
System.Data.sqlClient.sqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,String method) +53
System.Data.sqlClient.sqlCommand.ExecuteReader(CommandBehavior behavior,String method) +134
System.Data.sqlClient.sqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +41
System.Data.Common.DbCommand.ExecuteReader() +12
System.Data.Linq.sqlClient.sqlProvider.Execute(Expression query,QueryInfo queryInfo,IObjectReaderFactory factory,Object[] parentArgs,Object[] userArgs,ICompiledSubQuery[] subQueries,Object lastResult) +1306
System.Data.Linq.sqlClient.sqlProvider.ExecuteAll(Expression query,QueryInfo[] queryInfos,Object[] userArguments,ICompiledSubQuery[] subQueries) +118 System.Data.Linq.sqlClient.sqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) +342
System.Data.Linq.DataContext.ExecuteMethodCall(Object instance,MethodInfo methodInfo,Object[] parameters) +83

所有其他存储过程都以相同的方式调用,但没有一个存在此问题.远程数据库管理员说他可以在超时发生之前看到呼叫开始和结束,所以它似乎与Linq收到数据后的步骤有关.

有没有人经历过这个以及任何想法如何解决它?

我尝试从dmbl文件删除SP并重新添加它.它注意到其中一个值从十进制变为双精度,但除此之外全部相同.

一如既往,昨天工作正常!

提前致谢.

解决方法

好吧,我终于发现了这个问题的真实答案. SSMS通常使用ARITHABORT ON,代码通常使用ARITHABORT OFF – 这基本上是如何处理代码中的数学行有错误时发生的情况的选项 – 例如除以零.

但是,这里的主要内容是两种方法都有不同的执行计划 – 这就是为什么同样的事情可以(随机)在网站上花费比在SSMS中更长的时间.

执行计划是根据第一次使用时的估计编译的,因此您随机发现的是执行计划以一种非常适合您第一次查询的方式缓存,但对后续查询来说非常糟糕.这就是这里发生的事情,这也是它突然重新开始工作的原因 – 在更改存储过程后创建了一个新的查询计划.

最后我们在存储过程中使用WITH RECOMPILE – 因此没有有效的重复使用执行计划,但我们没有注意到任何差异,并且此后没有发生问题.

猜你在找的MsSQL相关文章