Sql server 存储过程在通过RPC调用时有时会超时,但在SQL中调用时总是OK

Sql server 存储过程在通过RPC调用时有时会超时,但在SQL中调用时总是OK,sql-server,sql-server-2008,stored-procedures,sql-server-2008-r2,rpc,Sql Server,Sql Server 2008,Stored Procedures,Sql Server 2008 R2,Rpc,我们有一个非常奇怪的问题: 我们有一个存储过程,它返回一组数据。此过程执行相当复杂的连接和聚合,因此需要700毫秒才能执行 当直接在SQLStudio中调用时,该过程总是返回correcty,并且总是需要大约700毫秒的时间 但是,当通过客户端软件(C#或Excel)调用时,它会工作一段时间,但突然,该过程需要30秒(!)并超时。磁盘读取次数正常,但CPU正在上升 这种行为持续1-2小时,然后又恢复正常!在此期间,当过程显示此行为时,您仍然可以在SQL Studio中执行该过程。此外,在客户端调

我们有一个非常奇怪的问题:

我们有一个存储过程,它返回一组数据。此过程执行相当复杂的连接和聚合,因此需要700毫秒才能执行

当直接在SQLStudio中调用时,该过程总是返回correcty,并且总是需要大约700毫秒的时间

但是,当通过客户端软件(C#或Excel)调用时,它会工作一段时间,但突然,该过程需要30秒(!)并超时。磁盘读取次数正常,但CPU正在上升

这种行为持续1-2小时,然后又恢复正常!在此期间,当过程显示此行为时,您仍然可以在SQL Studio中执行该过程。此外,在客户端调用时,其他更简单的过程也会正常执行

我用探查器检查了电话。通过客户端调用时,调用标记为“RPC”,在SQL Studio中调用时,它标记为“SQL”

因此,该过程可能正常执行,但通过RPC的数据传输不知何故挂起。但这只是一个猜测

有没有人有什么想法,或者能为我们指明方向?我不知道去哪里找。
事件日志也是空的。

.NET应用程序使用预定义的(默认)命令超时值。 对于某些命令和查询,此持续时间可能不够。 您可以尝试在应用程序中定义自定义命令超时

我认为您使用了前面提到的C#应用程序。在数据库上下文的构造函数中遵循以下定义(EF代码优先方法)可能会解决您的问题

public MyDBContext()
      : base("MyDB")
  {
      ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 300;
  }
我在基于C#的应用程序中使用了这个定义,并与执行sql server存储过程的EF一起使用


祝你好运

问题解决了——这是一个相当复杂的函数,编译执行计划花费了很多时间。我通过删除大量条件分支(if、case)并将过程拆分为多个子过程来简化过程。

google或bing“参数嗅探”以查看这是否是一个可能的问题。@GranadCoder有趣的文章,但您认为这与通过RPC的调用有关吗?只有在通过RPC调用过程时才会出现问题。如果通过SQL(在SQL Studio中)调用,那么它总是有效的。对我们来说,RPC组件中似乎发生了一些事情(如缓冲区溢出或错误的队列处理),但我们不知道应该在哪里查找。谢谢,我也在寻找延长超时的方法。但在我们的情况下,我们非常确定我们还有另一个问题。如前所述,该过程通常需要约1秒。只是有时候,当通过RPC调用时,服务器的某些部分会“卡住”,然后它需要永远保持。这只会通过RPC调用发生,在SQLStudio中它总是有效的。此外,探查器说磁盘上的读取次数是正常的,只有CPU会永远上升。对我们来说,这看起来像是RPC调用上的一些队列处理进入了循环或其他状态,但我们不知道应该在哪里查找我现在遇到了类似的问题。我有一个存储过程,当我在SQLServerManagementStudio中运行它时,大约需要4秒钟(删除80.000条记录)。但是,当我从C#(在我的web服务类visualstudio中)运行它时,它有一个超时。我看不到简化查询(存储过程)或拆分查询的方法(它通过左外join/min(id)/group语句查找重复项,非常大)。有什么想法吗?修正了!我需要将带有重新编译的
添加到我的过程中。我没有帮助一些人,但这解决了我的问题。通过删除300.000条记录进行测试,大约需要15秒(其中80.000条记录在SSMS中需要4秒)@Tjab创建存储过程时,SQL Server会创建一个所谓的查询计划,该计划基于对数据的统计信息。通常,在创建过程时,此计划仅创建一次。现在可能会发生这样的情况:您的数据发生了更改,以至于查询计划不再适合数据。在这种情况下,带有“重新编译”的选项
“强制sql server在每次执行存储过程时刷新查询计划”。@Tjab顺便说一句,当您删除大量数据时,表上的索引会减慢删除速度。它可以帮助暂时禁用索引并重新创建。当然,这取决于你的数据结构。我想我得调查一下。我对数据库了解不够,无法回答以下问题:;我的数据库中有超过3.9亿条数据记录,索引空间为55GB。当我禁用并重新创建索引时,会不会很难崩溃(或者至少需要很长时间才能崩溃?)?