更改过程或触发器中的SET选项将导致重新编译

本文探讨了在存储过程或触发器中使用SET选项可能导致的不必要的重新编译问题,这可能影响SQL Server的性能。SQL Prompt的性能规则PE012建议避免在这些对象中使用影响计划重用的SET语句,因为它们可能导致计划缓存中的计划无法重用,从而增加CPU成本和编译时间。文章解释了重新编译的原因,包括SET选项的更改,以及如何通过扩展事件或SQL Server Profiler调查过度重新编译。
摘要由CSDN通过智能技术生成

SQL Prompt根据数据库的对象名称、语法和代码片段自动进行检索,为用户提供合适的代码选择。自动脚本设置使代码简单易读--当开发者不大熟悉脚本时尤其有用。SQL Prompt安装即可使用,能大幅提高编码效率。本教程介绍了SQL Prompt的性能规则PE012,该规则将建议您是否在存储过程或触发器中检测到SET语句的使用,这可能会导致不必要的重新编译,尽管问题涉及其他类型的批处理。

有时,由于某种显而易见的原因,您将有一个存储过程或触发器间歇地花费更长的时间运行。您已经检查了索引,排除了诸如参数嗅探之类的问题,但是间歇性的性能问题仍然存在。SET为了更改执行设置,是否可以像您在批处理中发出语句那样简单呢?如果这样做,则可能是由于SQL Server需要重新编译该过程或重复触发而导致了该问题。

重新编译没有什么特别的错误,实际上,强制执行某些查询在每次执行时重新编译是很常见的,正是为了避免与参数嗅探、滥用Execute()或包罗万象的查询有关的不良性能问题。但是,如果重新编译变得过多,尤其是对于频繁或昂贵的查询,则可能会成为问题,值得调查原因,我将向您展示如何使用扩展事件。

什么是重新编译?

当SQL Server执行临时批处理或查询或诸如存储过程或触发器之类的对象时,SQL Server将为每个批处理或对象以及该批处理或对象中的每个查询编译针对当前状态进行优化的执行计划数据库,其对象及其数据。SQL Server的优化器设计此计划需要花费时间和资源,但是必须在代码可以传递到执行引擎之前完成。幸运的是,我们倾向于重复执行相同的查询或过程,可能使用不同的参数,因此SQL Server将其生成的大多数计划存储在计划缓存中,并且无论我们使用什么参数值,都将确保所有计划都可以安全地重用。当我们再次执行相同的批处理或对象时,只要有可能,它将简单地重用其缓存的计划。

但是,有时我们会重新执行存储过程,或者重新提交批处理或查询优化器之前已见过的缓存,并且针对该优化器在缓存中具有优化的计划,但是由于某些原因,它无法重用该计划并编译一个新的。这是重新编译,并且由于各种原因而发生。如果执行引擎检测到表已更改或其统计信息已发生重大变化,它将自动发生,这时它将标记要重新编译访问该表的查询的所有缓存计划。下次运行其中一个查询时,优化器将生成新计划,而旧计划将被删除。

我们还可以通过将OPTION (RECOMPILE)提示附加到查询来强制优化器不断重新编译计划。该查询的计划可能仍在高速缓存中,但不会被重用。通常这样做是为了处理由于参数嗅探,使用“catch-all”过程,滥用Execute()等等所导致的不稳定性能。

为了节省时间和资源,SQL Server会在可能的情况下进行语句级的重新编译。如果批处理或存储过程中仅一个语句的计划因数据结构或数据的基础更改而无效,或者只有一个语句具有OPTION (RECOMPILE)提示,则仅重新编译受影响的语句的计划,而不重新编译整个批处理或存储。

有时,重新编译既不会因数据结构或数据的更改而自动触发,也不会由于使用提示而被强制执行。我们在同一数据库上重新执行相同的查询,存在一个匹配的缓存计划,因为提交的查询的SQL文本和与该缓存计划相关联的SQL文本完全匹配(包括空格和回车符),但是该计划没有被重用。

再次,有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值