如何清除特定語句的執行計劃緩存
轉載自:
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語句的執行計劃是否得到優化。