SqlServer 中如何查看某一個Sql語句是復用了執行計划,還是重新生成了執行計划


我們知道SqlServer的查詢優化器會將所執行的Sql語句的執行計划作緩存,如果后續查詢可以復用緩存中的執行計划,那么SqlServer就會為后續查詢復用執行計划而不是重新生成一個新的執行計划,因為復用執行計划的性能比生成執行計划的性能要高很多,所以SqlServer的這一特性可以大大提高Sql語句的執行效率。特別是對於存儲過程,因為存儲過程的執行計划是在存儲過程第一次執行的時候生成的,存儲過程的執行計划生成后就會被緩存到SqlServer的執行計划列表中,如果以后存儲過程再被執行,那么存儲過程的執行計划就可以被復用(除非查詢優化器認為該存儲過程的執行計划已經過時,否則一般都會被復用),性能大大提升。

 

那么現在我們怎么才能知道執行的Sql語句是復用的SqlServer緩存的執行計划,還是重新生成的執行計划呢?

我們可以通過Sql Server Profiler這個工具來看到執行計划是否被查詢優化器復用。

首先打開Sql Profiler,新建一個跟蹤

然后在 事件選擇 面板上選中 顯示所有事件

然后在事件列表里面,選中 Stored Procedures 類別下的 SP:CacheHit SP:CacheMiss 事件,如果Sql Profiler中出現了SP:CacheHit事件表示SqlServer為查詢語句復用了緩存中的執行計划,如果出現了SP:CacheMiss 事件表示SqlServer為查詢語句重新生成了執行計划

接着我們隨便執行一個Sql語句如下

select * from [dbo].[T_People]

從下圖中我們發現在Sql Profiler出現了SP:CacheMiss 事件,因為我們是在SqlServer中第一次執行該查詢,所以SqlServer的緩存列表中並沒有該查詢語句的執行計划,所以SqlServer為該查詢語句重新生成了執行計划。

接着我們再次執行上面的查詢語句,這一次Sql Profiler出現了SP:CacheHit  事件,說明SqlServer這次為查詢語句復用了緩存中的執行計划,並沒有重新生成執行計划。

 

使用如下語句可以清除SqlServer目前所有緩存的執行計划,為所有Sql語句重新生成執行計划,切記不要在客戶生產環境上執行如下語句!

DBCC FREEPROCCACHE

 

所以通過Sql Profiler我們可以跟蹤到執行的每條Sql語句是否重新生成了執行計划,從而知道對查詢性能的影響是什么。對於SqlServer是否會為查詢語句復用執行計划也是一個非常復雜的問題,諸如查詢條件參數化這樣的手段都可以增加執行計划的復用性,有興趣的朋友可以參考下面三篇文章做詳細了解,這三篇文章都詳細地解釋了SqlServer執行計划的復用機制,寫的非常全面。

談一談SQL Server中的執行計划緩存(上)
談一談SQL Server中的執行計划緩存(下)
執行計划的重用

 

另外關於SqlServer緩存的執行計划何時會被刪除找到了下面這篇網摘供參考

什么情況下會刪除執行計划

在沒有人工手動清除緩存的情況下,如果出現內存不足的情況下SQL Server會自動清除一部分沒被利用到的緩存計划。

所有緩存的最大大小取決於max server memory的大小。

 

怎樣判斷需要刪除的執行計划

果存在內存不足的情況,數據庫引擎將使用基於開銷的方法來確定從過程緩存中刪除哪些執行計划。怎樣確定一個執行計划的開銷呢,對於一個第一次執行的執行計划SQL Server將它的開銷值設為0,被多次執行過的執行計划SQL Server將它的開銷值設置為原始編譯開銷,所以數據庫引擎會重復檢查每個執行計划的狀態並將刪除當前開銷為零的執行計划。如果存在內存不足的情況,當前開銷為零的執行計划不會自動被刪除,而只有在數據庫引擎檢查該執行計划並發現其當前開銷為零時,才會刪除該計划。當檢查執行計划時,如果當前沒有查詢使用該計划,則數據庫引擎將降低當前開銷以將其推向零。

數據庫引擎會重復檢查執行計划,直至刪除了足夠多的執行計划,以滿足內存需求為止。如果存在內存不足的情況,執行計划可多次對其開銷進行增加或降低。如果內存不足的情況已經消失,數據庫引擎將不再降低未使用執行計划的當前開銷,並且所有執行計划都將保留在過程緩存中,即使其開銷為零也是如此。

 

重新編譯執行計划

根據數據庫新狀態的不同,數據庫中的某些更改可能導致執行計划效率降低或無效。SQL Server 將檢測到使執行計划無效的更改,並將計划標記為無效。此后,必須為執行查詢的下一個連接重新編譯新的計划。導致計划無效的情況包括:

•對查詢所引用的表或視圖進行更改(ALTER TABLE 和 ALTER VIEW)。

•對執行計划所使用的任何索引進行更改。

•對執行計划所使用的統計信息進行更新,這些更新可能是從語句(如 UPDATE STATISTICS)中顯式生成,也可能是自動生成的。

•刪除執行計划所使用的索引。

•顯式調用 sp_recompile。

•對鍵的大量更改(其他用戶對由查詢引用的表使用 INSERT 或 DELETE 語句所產生的修改)。

•對於帶觸發器的表,插入的或刪除的表內的行數顯著增長。

•使用 WITH RECOMPILE 選項執行存儲過程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM