哪些因素可能导致SQL Server上的存储过程重新编译?

时间:2012-01-29 14:55:20

标签: sql-server performance stored-procedures

我应该注意哪些因素会导致过多的存储过程重新编译?

将导致存储过程重新编译的代码示例将非常有用。目的是避免重新编译,如果可能的话,应该提高性能。

导致不同输出的动态SQL和变量路径(通过数据类型和/或列数)似乎可能会出现问题。这些假设是否正确?还有其他例子。

编辑:我找到了另一个例子。在流控制语句中创建临时表将导致重新编译。

3 个答案:

答案 0 :(得分:18)

有几种方法可以确保重新编译存储过程:

  • 使用WITH RECOMPILE
  • 使存储过程动态化(想想exec()
  • 使用sp_recompile标记要重新编译的proc。
  • 更改缓存查询计划所依赖的架构
  • 致电DBCC FREEPROCCACHE
  • 在查询级别,可以使用RECOMPILE查询提示重新编译proc中的单个语句(SQL 2008)。

重新编译中的因素

除了上面列出的硬因素之外,是什么导致存储过程重新编译?好吧,很多东西。其中一些与上面的列表交织在一起,但我想重新呈现它们b / c它可能不是很明显。

  • 插入或删除大量数据(索引和表格中的数据密度通常控制查询计划)
  • 重建索引(对基础对象的更改)
  • 创建/删除临时表(同样,基础DML更改)。
  • 查询计划老化了(想想最近没用过,而sql想要清理内存使用)

这绝不是一份详尽的清单。无论您使用SQL Server多长时间,查询优化器都会发展变得惊人。但是这里有一些可能有用的资源:

但等待更多!

话虽如此,你的问题中的假设是重新编译总是对性能不利。事实上,经常补偿是好的。

那么你什么时候想要它重新编译?让我们看一个按姓氏搜索的proc的例子。存储过程执行'parameter sniffing'这是一个祝福(如果它适用于你)和一个诅咒(如果它对你不利)。首先,有人在Zebr%上搜索zerbrowski。姓氏索引意识到这是非常具体的,并且将返回,比如说,从一百万行中返回3行 - 因此构建了一个执行计划。在为低行结果编译proc时,下一次搜索是S%。嗯,S是你最常见的名字,在100万中匹配93,543行。

答案 1 :(得分:1)

某些SET选项可能导致存储过程重新编译甚至一次执行多次重新编译!

其中一些选项甚至可能不在SP内部

--this will cause recompilation
SET concat_null_yields_null ON;
EXEC spMyProc;

在SP内部导致重新编译的一些选项:

ARITHABORT

ANSI_NULLS

QUOTED_IDENTIFIER

幸运的是,这个不会导致重新编译:SET NOCOUNT ON;

答案 2 :(得分:0)

可选/可变数字参数也可能看起来像重新编译,因为计划是针对特定参数列表进行缓存的。

在通过连接将语句转换为SP的情况下(希望将来再次使用),将提取值并对其进行参数化。

如果这些参数包括调用方动态填充的IN子句之类的参数,则参数列表很少匹配,并且您会看到每次IN子句包含不同数量的值时都会生成新计划。