如何清除特定语句的执行计划缓存
2013-06-17 13:29
316 查看
SQL server运行到一定的时候, 执行计划的缓存可能会相当大,有些能到几个GB的大小。这个时候假设某个语句比较复杂而且SQL server 生成的执行计划不够优化,你希望把该执行计划的缓存清除使得SQL server能够重新编译该语句。该如何做呢?
如果是存储过程则很好办,直接使用sp_recompile就可以了,如下所示。如果参数是表,那么所有用到该表的存储过程或trigger都会重新编译,从而把原来的plan 替换掉:
USE AdventureWorks;
GO
EXECsp_recompileN'Sales.Customer';
GO
如果是一般的语句呢? 比如下面的语句:
use AdventureWorks
go
http://blogs.msdn.com/b/apgcdsd/archive/2013/03/13/10401823.aspx
SELECT*FROM Sales.SalesOrderHeader h, Sales.Customer c,Sales.SalesTerritory t
WHERE h.CustomerID = c.CustomerID
AND c.TerritoryID = t.TerritoryID
AND CountryRegionCode = N'CA';
我执行上面的语句几次后,观察下执行计划的缓存:
SELECT usecounts,text,plan_handle,*FROMsys.dm_exec_cached_plans cp
CROSSAPPLY sys.dm_exec_query_plan(cp.plan_handle)
CROSSAPPLY sys.dm_exec_sql_text (cp.plan_handle)
wheretextlike
'%SELECT * FROM Sales.SalesOrderHeader h, Sales.Customer c,Sales.SalesTerritory t
WHERE h.CustomerID = c.CustomerID
AND c.TerritoryID = t.TerritoryID
AND CountryRegionCode%';
得到结果如下:
Usecounts表示该语句被执行了7次。 如果这个语句的执行计划不好,如何删除它呢?
如果是SQL server 2008 R2就很好办,直接使用DBCC FREEPROCCACHE然后传入plan handle如即可,如:
DBCC FREEPROCCACHE(0x060001002903DC0B4001B887000000000000000000000000)
但是SQL server 2005的FREEPROCCACHE并没有这个用法。 SQL 2005里面如果运行DBCC FREEPROCCACHE那么所有的缓存都会被清空了。这对性能的影响比较大,因为SQL server 要对所有的语句重新编译然后重新生成缓存。SQL server 2005里面有没有其他方法只清除特定的语句的缓存呢?
有的,答案就使用使用plan guide如下:
sp_create_plan_guide
@name = N'recompile_Guide',
@stmt =
N'SELECT * FROM Sales.SalesOrderHeader h, Sales.Customer c,Sales.SalesTerritory t
WHERE h.CustomerID = c.CustomerID
AND c.TerritoryID = t.TerritoryID
AND CountryRegionCode = N''CA'';',
@type = N'SQL',
@module_or_batch =NULL,
@params =NULL,
@hints = N'OPTION (RECOMPILE)'
go
exec sp_control_plan_guide N'drop',N'recompile_Guide'
上面的sp_create_plan_guide使用RECOMPILE参数,意思是说,每次碰到该语句,必须重新编译。sp_create_plan_guide运行后,该语句的执行计划缓存就被删除了,下次该语句再次执行就会重新编译。那么我为什么马上又删除这个plan guide呢?因为该语句的缓冲被清除后,我不希望该语句每次执行都重新编译,所以我删除了它,毕竟我执行sp_create_plan_guide的目的是删除该语句的执行计划缓存而已。所以如果你使用同样的手段,务必记得立即把sp_create_plan_guide建立的guide删除。
如果是存储过程则很好办,直接使用sp_recompile就可以了,如下所示。如果参数是表,那么所有用到该表的存储过程或trigger都会重新编译,从而把原来的plan 替换掉:
USE AdventureWorks;
GO
EXECsp_recompileN'Sales.Customer';
GO
如果是一般的语句呢? 比如下面的语句:
use AdventureWorks
go
http://blogs.msdn.com/b/apgcdsd/archive/2013/03/13/10401823.aspx
SELECT*FROM Sales.SalesOrderHeader h, Sales.Customer c,Sales.SalesTerritory t
WHERE h.CustomerID = c.CustomerID
AND c.TerritoryID = t.TerritoryID
AND CountryRegionCode = N'CA';
我执行上面的语句几次后,观察下执行计划的缓存:
SELECT usecounts,text,plan_handle,*FROMsys.dm_exec_cached_plans cp
CROSSAPPLY sys.dm_exec_query_plan(cp.plan_handle)
CROSSAPPLY sys.dm_exec_sql_text (cp.plan_handle)
wheretextlike
'%SELECT * FROM Sales.SalesOrderHeader h, Sales.Customer c,Sales.SalesTerritory t
WHERE h.CustomerID = c.CustomerID
AND c.TerritoryID = t.TerritoryID
AND CountryRegionCode%';
得到结果如下:
Usecounts表示该语句被执行了7次。 如果这个语句的执行计划不好,如何删除它呢?
如果是SQL server 2008 R2就很好办,直接使用DBCC FREEPROCCACHE然后传入plan handle如即可,如:
DBCC FREEPROCCACHE(0x060001002903DC0B4001B887000000000000000000000000)
但是SQL server 2005的FREEPROCCACHE并没有这个用法。 SQL 2005里面如果运行DBCC FREEPROCCACHE那么所有的缓存都会被清空了。这对性能的影响比较大,因为SQL server 要对所有的语句重新编译然后重新生成缓存。SQL server 2005里面有没有其他方法只清除特定的语句的缓存呢?
有的,答案就使用使用plan guide如下:
sp_create_plan_guide
@name = N'recompile_Guide',
@stmt =
N'SELECT * FROM Sales.SalesOrderHeader h, Sales.Customer c,Sales.SalesTerritory t
WHERE h.CustomerID = c.CustomerID
AND c.TerritoryID = t.TerritoryID
AND CountryRegionCode = N''CA'';',
@type = N'SQL',
@module_or_batch =NULL,
@params =NULL,
@hints = N'OPTION (RECOMPILE)'
go
exec sp_control_plan_guide N'drop',N'recompile_Guide'
上面的sp_create_plan_guide使用RECOMPILE参数,意思是说,每次碰到该语句,必须重新编译。sp_create_plan_guide运行后,该语句的执行计划缓存就被删除了,下次该语句再次执行就会重新编译。那么我为什么马上又删除这个plan guide呢?因为该语句的缓冲被清除后,我不希望该语句每次执行都重新编译,所以我删除了它,毕竟我执行sp_create_plan_guide的目的是删除该语句的执行计划缓存而已。所以如果你使用同样的手段,务必记得立即把sp_create_plan_guide建立的guide删除。
相关文章推荐
- 如何清除特定语句的执行计划缓存
- 有时一个表的某个字段明明有索引,当观察一些语句的执行计划确不走索引呢?如何解决 ?
- 如何通过10053查看SQL语句执行计划
- 清除某语句执行计划,降低CPU
- 如何使用SQLPLUS分析SQL语句(查询执行计划跟踪)
- 如何让SQL语句的执行计划稳定不变-存储概要介绍(转)
- 清除SQL Server数据缓存和执行计划缓存,查看执行计划的各种方式对比
- Oracle 如何根据动态性能视图来查看某条SQL语句的执行计划
- SQL命令:清除数据缓存和执行计划缓存,查看执行计划
- SQL 优化SQL查询:如何写出高性能SQL语句-- sql执行计划
- 查看Oracle执行计划的几种方法 / oracle中DateTime类型的字段,建立索引后,查寻时索引如何生效?/ oracle 中sql语句怎么加多个强制索引
- 如何用参数化SQL语句污染你的计划缓存
- 如何使用SQLPLUS分析SQL语句(查询执行计划跟踪)
- 清除SQL Server数据缓存和执行计划缓存,查看执行计划的各种方式对比
- 如何清除某条SQL的执行计划
- 如何根据执行计划,判断Mysql语句是否走索引
- 如何在sqlplus中查看oracle数据库sql语句执行计划,执行时间和统计信息
- 清除SQL Server数据缓存和执行计划缓存,查看执行计划的各种方式对比
- 如何用参数化SQL语句污染你的计划缓存
- Oracle优化——如何查看语句的准确的执行计划(explain plan可能不是真实的)