我应该注意哪些因素会导致过多的存储过程重新编译?
将导致存储过程重新编译的代码示例将非常有用。目的是避免重新编译,如果可能的话,应该提高性能。
导致不同输出的动态SQL和变量路径(通过数据类型和/或列数)似乎可能会出现问题。这些假设是否正确?还有其他例子。
编辑:我找到了另一个例子。在流控制语句中创建临时表将导致重新编译。
答案 0 :(得分:18)
有几种方法可以确保重新编译存储过程:
WITH RECOMPILE
,exec()
)sp_recompile
标记要重新编译的proc。 DBCC FREEPROCCACHE
重新编译中的因素
除了上面列出的硬因素之外,是什么导致存储过程重新编译?好吧,很多东西。其中一些与上面的列表交织在一起,但我想重新呈现它们b / c它可能不是很明显。
这绝不是一份详尽的清单。无论您使用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子句包含不同数量的值时都会生成新计划。