1. 什么是执行计划缓存?
在SQL Server中,执行计划是查询语句在被执行前的一个重要步骤。执行计划缓存是SQL Server的重要组成部分之一。它是SQL Server中的一个内存区域,用于存储查询语句的执行计划以及其他相关信息。当一个查询语句被执行时,SQL Server首先查看执行计划缓存中是否已经存在该查询语句的执行计划。如果已经存在,SQL Server会直接使用缓存中的执行计划,从而避免了查询语句重新编译的时间。
1.1 为什么需要执行计划缓存?
执行计划缓存的存在是为了提高SQL Server的性能。在SQL Server中,一个查询语句的执行需要多个步骤,包括查询解析、编译、优化和执行。其中,编译和优化是比较耗时的步骤,因为它需要分析查询语句的各个部分,确定最佳的执行计划。
如果一个查询语句被频繁执行,每次都需要重新编译和优化,将会浪费SQL Server的大量资源和时间。这时,就需要执行计划缓存。当查询语句被执行时,SQL Server首先查看执行计划缓存中是否有相应的执行计划。如果有,就直接使用缓存中的执行计划,从而避免了编译和优化的过程,提高了查询的性能。
2. 执行计划缓存的种类
在SQL Server中,执行计划缓存可以分为两种类型:对象级别的执行计划缓存和计划级别的执行计划缓存。
2.1 对象级别的执行计划缓存
对象级别的执行计划缓存是与数据库对象相关的,例如存储过程、函数和触发器等。存储过程和函数等对象都可以有自己的执行计划缓存,这些执行计划缓存是在对象被编译时创建的,可以重复使用。当对象被修改后,相应的对象级别的执行计划缓存会被清除。
2.2 计划级别的执行计划缓存
计划级别的执行计划缓存是针对单个查询语句的。当一个查询语句被执行时,SQL Server会检查计划级别的执行计划缓存中是否已经存在该查询语句的执行计划。如果已经存在,就直接使用缓存中的执行计划。计划级别的执行计划缓存对短时间内频繁执行的查询语句有很大的优化效果。
3. 执行计划缓存的管理
SQL Server使用一定的规则来管理执行计划缓存。执行计划缓存中的执行计划会被自动清除,以保证SQL Server的稳定性。
3.1 执行计划缓存的自动清除
SQL Server会按照一定的规则来自动清除执行计划缓存中的内容。当执行计划缓存中的缓存计数或缓存的物理大小超过一定的阈值时,SQL Server会清理一部分执行计划缓存。
-- 查看缓存计数和缓存物理大小
SELECT OBJECT_NAME(st.objectid) AS proc_name,
cached_time,
usecounts,
size_in_bytes/1024 AS size_in_kb,
st.text
FROM sys.dm_exec_cached_plans tp
CROSS APPLY sys.dm_exec_sql_text(plan_handle) st
ORDER BY usecounts DESC
上述代码中使用了SQL Server提供的动态管理视图sys.dm_exec_cached_plans和sys.dm_exec_sql_text,可以查询当前SQL Server的执行计划缓存中的缓存计数和缓存的物理大小。
3.2 执行计划缓存的手动清除
在某些情况下,手动清除执行计划缓存可能是必要的。例如,在对数据库进行大规模改动或者进行优化时,手动清除执行计划缓存可以避免缓存中的执行计划过时或无效。
可以使用以下两种方法手动清除执行计划缓存:
3.2.1 DBCC命令
-- 清除整个执行计划缓存
DBCC FREEPROCCACHE
-- 清除指定计划
DBCC FREEPROCCACHE (plan_handle)
3.2.2 系统存储过程
-- 清除整个执行计划缓存
EXEC sys.sp_flush_cache
-- 清除指定计划
EXEC sys.sp_flush_cache @plan_handle
4. 微调执行计划缓存
虽然执行计划缓存可以提高SQL Server的性能,但是在某些情况下,缓存中的执行计划可能不是最佳的或者过时的,这时需要微调执行计划缓存。
4.1 迫使SQL Server编译新的执行计划
当一个查询语句被执行时,SQL Server会查看执行计划缓存中是否已经存在该查询语句的执行计划。如果已经存在,就直接使用缓存中的执行计划。如果希望SQL Server编译新的执行计划,可以使用以下两种方法。
4.1.1 重置计划缓存
-- 重置计划缓存
DBCC FREEPROCCACHE
-- 执行查询语句
SELECT * FROM table_name
4.1.2 使用WITH RECOMPILE选项
在执行查询语句时,在SELECT关键字之前加上WITH RECOMPILE选项,SQL Server将强制重新编译这个查询语句,从而生成新的执行计划。
-- 使用WITH RECOMPILE选项
SELECT * FROM table_name WITH RECOMPILE
4.2 修改查询语句和索引
如果缓存中的执行计划不是最佳的,可以考虑修改查询语句或创建或删除索引等操作,从而生成新的执行计划,提高查询性能。
5. 小结
执行计划缓存是SQL Server的重要组成部分之一,它用于提高SQL Server的性能。执行计划缓存可以分为对象级别的执行计划缓存和计划级别的执行计划缓存。SQL Server会按照一定的规则来管理执行计划缓存,定期清除缓存中的过时和无效的执行计划。
在某些情况下,缓存中的执行计划可能不是最佳的或者过时的,这时需要手动清除执行计划缓存或者微调执行计划缓存。可以使用DBCC命令或系统存储过程手动清除执行计划缓存,并可以使用重置缓存、使用WITH RECOMPILE选项、修改查询语句和索引等方法微调执行计划缓存。