据我所知,WITH RECOMPILE选项强制优化器重建存储过程的查询计划,但是你希望什么时候发生?

什么是关于何时使用WITH RECOMPILE选项以及何时不使用?

的一些经验法则

将它放在每个sproc上的相关开销是多少?

有帮助吗?

解决方案

正如其他人所说,你不希望在每个存储过程中简单地包含 WITH RECOMPILE 作为习惯。通过这样做,您将消除存储过程的主要好处之一:它保存了查询计划。

为什么这可能是一个大问题?计算查询计划比编译常规程序代码要强烈得多。因为SQL语句的语法只指定了你想要的什么,而不是(通常)如何来获取它,这使得数据库在创建物理时具有很大的灵活性计划(即实际收集和修改数据的分步说明)。有很多“技巧”。数据库查询预处理器可以做和选择它可以做什么 - 加入表的顺序,要使用的索引,是否在连接之前或之后应用 WHERE 子句等。

对于一个简单的SELECT语句,它可能没什么区别,但对于任何非平凡的查询,数据库将花费一些严重的时间(以毫秒为单位,而不是通常的微秒)来提出最佳计划。对于非常复杂的查询,它甚至不能保证最佳计划,它必须使用启发式方法来提出非常好的计划。因此,通过强制它每次重新编译,你告诉它必须一遍又一遍地完成这个过程,即使之前的计划非常好。

根据供应商的不同,应该有自动触发器来重新编译查询计划 - 例如,如果表上的统计信息发生显着变化(例如,某个列中的值的直方图开始随着时间的推移均匀分布变得高度倾斜),然后DB应该注意到并重新编译计划。但总的来说,数据库的实施者总体上比你更聪明。

与表演相关的任何内容一样,不要在黑暗中拍摄;弄清楚瓶颈所占的成本是你性能的90%,并先解决它们。

其他提示

将它放在每个存储过程上并不是一个好主意,因为编译查询计划是一项相对昂贵的操作,并且您不会看到缓存和重用查询计划的任何好处。

可以使用 sp_executesql 处理在存储过程中构建的动态where子句的情况,以执行TSQL,而不是将 WITH RECOMPILE 添加到存储过程。

另一个解决方案(SQL Server 2005以上)是使用 OPTIMIZE FOR 提示使用具有特定参数的提示。如果行中的值是静态的,那么这很有效。

SQL Server 2008引入了鲜为人知的功能称为” OPTIMIZE FOR UNKNOWN “:

  

此提示指示查询优化器   使用它具有的标准算法   如果没有参数值,总是使用   已经传递给查询了。   在这种情况下,优化器将会显示   在所有可用的统计数据   达到了什么的决心   用于的局部变量的值   生成查询计划应该是,   而不是看具体   传递给的参数值   应用程序的查询。

最常见的用法是在程序中可能有一个动态WHERE子句......你不希望为后续执行编译和保存该特定查询计划,因为它很可能不是完全相同的子句下次调用该过程时。

通常比 WITH RECOMPILE 更好的替代方法是 OPTION(RECOMPILE) 正如您在下面的解释中所看到的,取自此问题的答案

  

当遇到参数敏感问题时,常见的一块   论坛和Q& A网站上的建议是“使用重新编译”。 (假设   前面介绍的其他调整选项是不合适的)。不幸,   该建议经常被误解为意味着添加WITH RECOMPILE   存储过程的选项。

     

使用WITH RECOMPILE有效地将我们返回到SQL Server 2000   行为,每个都重新编译整个存储过程   执行。在SQL Server 2005及更高版本上,更好的选择是   在语句中使用OPTION(RECOMPILE)查询提示   遭受参数嗅探问题。此查询提示结果   仅重新编译有问题的陈述;执行计划   对于存储过程中的其他语句,将进行高速缓存和重用   像平常一样。

     

使用WITH RECOMPILE还表示已存储的已编译计划   过程未缓存。因此,没有性能信息   在DMV中维护,例如sys.dm_exec_query_stats。使用查询   相反提示意味着可以缓存已编译的计划和性能   DMV中提供了相关信息(尽管限制最多)   最近的执行,仅针对受影响的声明)。

     

对于至少运行SQL Server 2008 build 2746的实例(服务   包含累积更新的包1),使用OPTION(RECOMPILE)有另一个   与RECOMPILE相比的显着优势:仅OPTION(RECOMPILE)   启用参数嵌入优化。

只有在使用重新表达数据进行测试时才应该使用它,并且上下文表明不这样做会产生无效的查询计划(无论可能的原因是什么)。不要事先假设(未经测试)SP将无法正确优化。

仅手动调用的唯一例外(即不将其编码到SP中):当您知道自己已经大大改变了目标表的字符时。例如TRUNCATE,批量加载等

这是过早优化的另一个机会。

注意:我有很多要点。如果newby在下面提交了相同的答案,并且您同意,请提交他们的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top