【问题标题】:Stored Procedure runs slowly when being called from another stored procedure从另一个存储过程调用存储过程时运行缓慢
【发布时间】:2011-06-24 16:11:51
【问题描述】:

我有一个名为 resetflags 的存储过程 (sproc)。它需要一个 int 参数。另一个 sproc editInspection 调用它。 Sproc editInspection 是这样的:

  1. 更新表中的单行(持续时间
  2. 执行另一个存储过程(持续时间
  3. 执行 sproc resetFlags(持续时间 ~ 16 秒!!!)
  4. 选择单行(持续时间

如果我注释掉第 3 行并运行存储过程,它会在 0 秒内完成。 如果我自己运行第 3 行,它会在 1 秒内完成。 如果我注释掉第 1 行和第 2 行,sproc 需要 16 秒。

数据库不包含任何触发器(我是一个没有触发器的快乐人)。任何地方都没有用户分配的交易。我使用的是 SQL 2008 开发版。

我刚刚使用分析器对它和其他一些测试脚本进行了计时。以下是我的发现:

案例 1:运行脚本以执行带参数的 sproc editInspection。耗时 16000 毫秒。

案例 2:创建了一个测试脚本。更改为 sproc editInspection 的代码,以便所有参数都是局部变量。为这些本地变量赋值,然后执行代码。花了大约 16000 毫秒。

案例 3:从 sproc editInspection 中注释掉“exec resetflags”,然后运行如下内容:

执行editInspection param1,...param n 执行resetflags param1

所以 sproc resetflag 现在在 sproc editInspection 之外运行。这需要 600-700 毫秒才能完成。

案例 4:从案例 2 中获取测试脚本。除了一个变量声明和赋值之外,其他所有内容都被注释掉了。除执行 resetFlags 之外的所有其他语句。所以脚本基本上是

声明 param1 int /* 注释掉声明 stmts / SET param1 = 某个值 / 注释掉 SET stmts 注释掉 SELECT、UPDATE 和 EXECUTE */ 执行resetFlags param1

这个耗时约 16000 毫秒。

案例 5:从案例 4 中复制代码并将其粘贴到新的查询窗口中。执行它,大约花了 700 毫秒!这是奇怪的部分。

案例 6:使用参数值执行 sproc resetFlags。花了大约 600 毫秒。

任何关于寻找什么的线索将不胜感激。我知道我没有发布代码/表格定义和示例数据。定义和代码都很大,我也比较懒。

【问题讨论】:

  • 存储过程是否在同一张表上运行?另外,可能是错误的参数嗅探
  • 两个存储过程都在使用多个表变量。
  • 更正:只有 sproc resetFlags 使用了几个表变量。其他存储过程不使用任何表变量。
  • @nathan:是的,两个存储过程都在一些公共表上运行。

标签: performance tsql stored-procedures nested


【解决方案1】:

我强烈建议 parameter sniffing 作为罪魁祸首。

【讨论】:

  • 是的,根据他列出的案例,我认为您可能是对的。
  • 很有可能。 editInspection 将所有参数分配给局部变量(它有大约 30 个参数),但 restFlags 使用一个参数并且没有分配给局部变量。所以我会在周一尝试改变它。谢谢。
  • 解决了这个问题。参数嗅探是问题所在。谢谢大家帮助我。
猜你喜欢
  • 1970-01-01
  • 2014-09-17
  • 2011-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多