从另一个存储过程调用时,存储过程运行缓慢

时间:2011-06-24 16:11:51

标签: performance tsql stored-procedures nested

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

  1. 更新表格上的单行(持续时间<0.00秒)
  2. 执行另一个sproc(持续时间<0.00秒)
  3. 执行sproc resetFlags(持续时间~16秒!!!)
  4. 选择单行(持续时间<0.00秒)
  5. 如果我注释掉第3行并运行它,它会在0秒内完成。 如果我自己运行第3行,它会在1秒内完成。 如果我注释掉第1行和第2行,那么sproc需要16秒。

    数据库不包含任何触发器(我是一个无触发器的快乐人)。任何地方都没有用户指定的交易。我正在使用SQL 2008 Dev版。

    我刚用计时器和其他一些测试脚本计时。以下是我的发现:

    案例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毫秒。

    任何关于寻找什么的线索都将非常感激。我知道我没有发布代码/表格定义和样本数据。定义和代码非常大,我也很懒惰。

1 个答案:

答案 0 :(得分:3)

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