SQL Server重复执行同查询时:复用缓存计划还是重新生成?
SQL Server查询执行计划复用与重编译规则
当SQL Server第二次执行相同查询时,优先复用缓存中的执行计划,但并非绝对——在特定场景下会放弃缓存,重新生成执行计划(即重编译)。以下是决定复用或重编译的核心标准:
一、满足复用的核心条件
要复用缓存计划,必须同时满足以下要求:
- 查询文本完全一致:包括空格、大小写、注释等细节(除非开启特定兼容设置,但默认是严格匹配)
- 会话执行设置一致:
SET ARITHABORT、SET QUOTED_IDENTIFIER、SET ANSI_NULLS等关键会话选项必须和生成原计划时完全相同,任何一项差异都会被判定为不同查询 - 对象权限匹配:执行查询的用户对涉及表、视图等对象的权限,必须与生成原计划时的权限一致
- 缓存计划未失效:原计划仍存在于计划缓存中(未被内存压力清理或手动命令清除)
二、触发重编译的常见场景
当存在以下任意一种情况时,SQL Server会放弃缓存计划,重新生成执行计划:
- 对象结构变更:查询涉及的表、视图、索引、约束等对象被修改(如添加列、删除索引、修改数据类型)
- 统计信息过期或更新:SQL Server依赖统计信息生成最优计划,当表数据量变化超过阈值(通常为数据量的20%,小表阈值更低),或手动执行
UPDATE STATISTICS更新统计信息时,会触发重编译 - 缓存计划被清除:内存不足时SQL Server主动释放计划缓存,或执行
DBCC FREEPROCCACHE、DBCC FREESYSTEMCACHE等命令手动清除缓存 - 参数化不兼容:原计划基于特定参数值生成(参数嗅探),新参数值会导致原计划性能极差;或数据库的强制参数化设置被修改
- 权限或上下文变更:执行查询的用户权限发生变化,或数据库的兼容性级别(
COMPATIBILITY_LEVEL)被修改 - 临时表或表变量变更:查询依赖的临时表结构/数据变化,或表变量的统计信息更新(SQL Server 2019+对表变量统计支持更完善)
- 触发器或存储过程变更:关联的触发器被修改,或存储过程本身被ALTER修改
内容的提问来源于stack exchange,提问作者Dhainik Suthar
相关产品推荐
相关产品推荐

