sql server 编译与重编译详解
SQL Server编译与重编译详解
当我们与SQL Server交互,无论是执行查询、批处理、存储过程或是动态SQL语句,背后都涉及一项关键过程——编译。编译不仅仅是语法的解释和语句的,更是为这些指令生成“执行计划”的过程。这个执行计划是SQL Server为指令的执行所选择的路径,这个过程需要评估涉及的对象的架构、统计信息以及指令的具体内容,从而选择一条SQL Server认为成本最低的执行路径。一旦执行计划生成,SQL Server会将其缓存起来,这就是所谓的“plan cache”。后续的相同指令可以直接使用缓存中的执行计划,而无需再次编译。这种情况称为执行计划的“重用”。
有时候即使面对完全相同的语句,SQL Server仍然会选择进行“重编译”,即再次进行编译过程。这无疑会消耗更多的资源,但在某些情况下是必要的。
执行计划重用的利弊
执行计划的选择直接关系到语句的执行速度。一个好的执行计划可能会使语句的执行速度比差的计划快几倍甚至上千倍。从这一角度看,每次运行语句都进行编译似乎是最优选择,以确保获得最佳的执行计划。SQL Server每秒可能需要处理成百上千的指令。如果每个指令都重新编译,将会消耗大量资源。SQL Server需要在编译与重编译之间寻找一个平衡点,以优化整体性能。
通过运行特定的指令,如从sys.[syscacheobjects]中选择,我们可以看到SQL Server当前缓存的执行计划。这有助于我们理解哪些执行计划正在被重用,哪些正在被重新编译。
重编译的发生场景
有几种情况会导致SQL Server选择重编译而不是重用缓存中的执行计划:
1. 当指令或批处理所涉及的任何对象(如表或视图)的架构发生变化时。例如,在表或视图上添加或删除字段、索引或约束条件等。对象的定义发生变化后,原有的执行计划可能不再适用,因此需要重编译。
2. 当用户在某个存储过程或触发器上运行sp_repile时。运行此存储过程后,下一次运行相关指令时将会发生重编译。
当用户在某个表或视图上执行了sp_repile操作时,所有引用该表或视图的存储过程在下一次运行前都需要进行重编译。这是一个重要的操作,因为它会影响到SQL Server的执行效率。有一些特定的操作会清除内存中的所有执行计划,迫使数据库进行重编译。这些操作包括但不限于:Detach一个数据库、数据库升级、运行DBCC freeproache、运行reconfigure语句以及修改数据库的字符集等。当执行这些操作时,SQL Server服务器缓存中的所有或特定数据库的执行计划都会被清除。
除此之外,当一些SET开关值发生变化时,如狼蚁网站SEO优化中所涉及的开关值,之前的执行计划无法再被重用。这些开关值包括ansi_null_dflt_off、ansi_null_dflt_on等,它们的变化会影响语句执行的行为和结果。当这些开关值发生变化时,SQL Server需要根据新的设置重新制定执行计划。
当表或视图上的统计信息发生变化时,例如手动更新统计信息或SQL Server自动发现需要更新时,涉及的语句都需要进行重编译。执行计划的重用并不一定是一件好事,而编译或重编译也不一定是一件坏事。虽然重用计划可以节省编译时间,降低CPU使用率和减少阻塞,但每次重用的计划并不一定是最合适的。参数嗅探(parameter sniffing)就是计划重用带来的一个典型负效应。对于经常运行的语句,尤其是执行速度较快的语句,其编译时间可能会占总时间的很大比例,对资源来说是一个浪费。但SQL Server能够在编译与重编译之间做出平衡,大多数情况下都能正常运行。
了解这些关于SQL Server执行计划的知识对于我们优化数据库性能至关重要。感谢大家的阅读和支持,希望这篇文章能给大家带来帮助和启示。在优化数据库的过程中,我们还需要考虑其他因素,如查询优化、索引设计等。只有全面了解和掌握这些知识,我们才能更好地管理和维护数据库,提高系统的性能和稳定性。
编程语言
- sql server 编译与重编译详解
- 解决Node.js使用MySQL出现connect ECONNREFUSED 127.0.0.1-
- JS操作JSON方法总结(推荐)
- JSP的request对象实例详解
- jquery实现网站列表切换效果的2种方法
- 判断时间的正则表达式
- angular框架实现全选与单选chekbox的自定义
- JavaScript中匿名函数的用法及优缺点详解
- React-router v4 路由配置方法小结
- PHP设置头信息及取得返回头信息的方法
- php实现图片局部打马赛克的方法
- 基于jQuery实现仿QQ空间送礼物功能代码
- PHP数组实例详解
- Eclipse的PHP插件PHPEclipse安装和使用
- javascript触发模拟鼠标点击事件
- 利用JQUERY实现多个AJAX请求等待的实例