如何清除特定語句的執行計劃緩存

如何清除特定語句的執行計劃緩存

轉載自:  
http://blogs.msdn.com/b/apgcdsd/archive/2013/03/13/10401823.aspx

 

SQL server運行到一定的時候, 執行計劃的緩存可能會相當大,有些能到幾個GB的大小。這個時候假設某個語句比較複雜而且SQL server 生成的執行計劃不夠優化,你希望把該執行計劃的緩存清除使得SQL server能夠重新編譯該語句。該如何做呢?

 

如果是存儲過程則很好辦,直接使用sp_recompile就可以了,如下所示。如果參數是表,那麼所有用到該表的存儲過程或trigger都會重新編譯,從而把原來的plan 替換掉:

 

USE AdventureWorks;
GO
EXEC sp_recompile N'Sales.Customer';
GO

 

如果是一般的語句呢? 比如下面的語句:

 

use AdventureWorks
go
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,* FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle)
CROSS APPLY sys.dm_exec_sql_text (cp.plan_handle)
where textlike
'%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刪除。

 

更新統計信息

轉載自:https://msdn.microsoft.com/zh-cn/library/hh510198.aspx

 

更新特定的統計信息對象

USE AdventureWorks;   
GO    
-- The following example updates the statistics for the AK_SalesOrderDetail_rowguid index of the SalesOrderDetail table.     
UPDATE STATISTICS Sales.SalesOrderDetail AK_SalesOrderDetail_rowguid;     
GO


更新表中的所有統計信息

USE AdventureWorks;    
GO    
-- The following example updates the statistics for all indexes on the SalesOrderDetail table.     
UPDATE STATISTICS Sales.SalesOrderDetail;     
GO


更新數據庫中的所有統計信息

USE AdventureWorks;    
GO    
-- The following example updates the statistics for all tables in the database.     
EXEC sp_updatestats;

 

提示(Hints)

轉載自:https://msdn.microsoft.com/zh-cn/library/ms187713.aspx

        https://msdn.microsoft.com/zh-cn/subscriptions/downloads/aa196160%28v=sql.80%29.aspx

 

提示分爲:

  • 聯接提示(Join Hints)

  • 查詢提示(Query Hints)

  • 表提示(Table Hints)

 

總結:


分析有性能問題的語句的時候,常常要根據它的執行計劃去分析性能消耗高的部分,定位到問題到底出在哪裏。

有的時候是需要更新統計信息;有的時候是需要優化SQL語句加上HINT提示。

最後查看SQL語句的執行計劃是否得到優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章