sql server 執行計畫的快取和重新使用

2021-08-30 18:13:19 字數 2747 閱讀 2908

執行計畫的快取和重新使用

sql server 2005 有乙個用於儲存執行計畫和資料緩衝區的記憶體池。池內分配給執行計畫或資料緩衝區的百分比隨系統狀態動態波動。記憶體池中用於儲存執行計畫的部分稱為過程快取。

sql server 2005 執行計畫包含下列主要元件:

在 sql server 2005 中執行任何 sql 語句時,關係引擎將首先檢視過程快取中是否有用於同一 sql 語句的現有執行計畫。sql server 2005 將重新使用找到的任何現有計畫,從而節省重新編譯 sql 語句的開銷。如果沒有現有執行計畫,則 sql server 2005 將為查詢生成新的執行計畫。

sql server 2005 有乙個高效的演算法,可查詢用於任何特定 sql 語句的現有執行計畫。在大多數系統中,這種掃瞄所使用的最小資源比通過重新使用現有計畫而不是編譯每個 sql 語句所節省的資源要少。

該演算法將新的 sql 語句與快取內現有的未用執行計畫相匹配,並要求所有的物件引用完全合法。例如,這兩個 select 語句中的第乙個語句與現有計畫不匹配,而第二個語句則匹配:

select * from person.contact

select * from adventureworks.person.contact

在 sql server 2000 和 sql server 2005 例項中,個別執行計畫重新使用的概率比在 sql server 6.5 及更早版本中高。

生成執行計畫後,它處於過程快取中。只有當需要空間時,sql server 2005 才使舊的未用計畫從快取老化掉。每個查詢計畫和執行環境都有相關的成本因子,可表明編譯結構所需的費用。這些資料結構還有乙個年齡字段。物件每由連線引用一次,其年齡欄位便按編譯成本因子遞增。例如,如果查詢計畫的成本因子為 8 並且被引用了兩次,則其年齡變為 16。惰性寫入器程序定期掃瞄過程快取中的物件列表。然後,惰性寫入器減少每個物件的年齡字段,每掃瞄一次減少 1。在本例中,查詢計畫的年齡經過 16 次過程快取掃瞄後減為 0,除非其他使用者引用了該計畫。如果滿足下面三個條件,惰性寫入器程序將釋放物件:

因為每次引用物件時其年齡欄位都會增加,所以經常被引用的物件的年齡字段不會減為 0,也不會從快取老化掉。不經常被引用的物件將很快滿足釋放條件,但是不會真被釋放,除非其他物件有記憶體需求。

根據資料庫的新狀態,資料庫內的某些更改可能會導致執行計畫效率低下或不再有效。sql server 檢測這些使執行計畫無效的更改,並將計畫標記為無效。此後,必須為執行查詢的下乙個連線重新編譯新的計畫。導致計畫無效的情況包括:

為了使語句正確,或要獲得可能更快的查詢執行計畫,大多數都需要進行重新編譯。

在 sql server 2000 中,如果批處理中的某條語句導致了重新編譯,則不管是通過儲存過程、觸發器、特殊批處理提交,還是通過準備好的語句提交,都將重新編譯整個批處理。在 sql server 2005 中,只有在批處理中導致重新編譯的語句才會被重新編譯。因為這個差異,在 sql server 2000 中將對重新編譯計數,而在 sql server 2005 中則不需要。而且,在 sql server 2005 中有更多型別的重新編譯,因為它擴充套件了功能集。

語句級重新編譯有助於提高效能,因為在大多數情況下,只有少數語句導致了重新編譯並造成相關損失(指 cpu 時間和鎖)。因此,避免了批處理中其他不必重新編譯的語句的這些損失。

在 sql server 2005 中,sql server profiler sp:recompile 跟蹤事件報告語句級重新編譯。在 sql server 2000 中,此跟蹤事件只報告批處理重新編譯。而且,在 sql server 2005 中,將填充此事件的 textdata 列。因此,不再需要 sql server 2000 中所使用的方法:必須跟蹤 sp:stmtstarting 或 sp:stmtcompleted 以獲得導致重新編譯的 transact-sql 文字。

sql server 2005 也新增了乙個新跟蹤事件,稱為 sql:stmtrecompile,它報告語句級重新編譯。它還可用於跟蹤和除錯重新編譯。只為儲存過程和觸發器生成 sp:recompile ,而為儲存過程、觸發器、特殊批處理、使用 sp_executesql 執行的批處理、準備好的查詢以及動態 sql 生成 sql:stmtrecompile。

sp:recompile 和 sql:stmtrecompile 的 eventsubclass 列都包含乙個整數**,用以指明重新編譯的原因。下表包含每個**號的意思。

eventsubclass 值

說明 架構已更改。

統計資訊已更改。

編譯已延遲。

set 選項已更改。

臨時表已更改。

遠端行集已更改。

for browse 許可權已更改。

查詢通知環境已更改。

分割槽檢視已更改。

游標選項已更改。

已請求 option (recompile)。

當 auto_update_statistics 資料庫選項被設定為 on 時,如果查詢以表或索引檢視為目標,而表或索引檢視的統計資訊自上次執行後已更新或基數已發生很大變化,查詢將被重新編譯。此行為適用於標準使用者定義表、臨時表以及由 dml 觸發器建立的 inserted 和 deleted 表。如果過多的重新編譯影響到查詢的效能,請考慮將此設定更改為 off。當 auto_update_statistics 資料庫選項設定為 off 時,不會發生基於統計資訊或基數變化的重新編譯。請注意,在 sql server 2000 中,即使此設定為 off,查詢仍然會基於 dml 觸發器 inserted 和 deleted 表的基數變化進行重新編譯。有關禁用 auto_update_statistics 的詳細資訊,請參閱索引統計資訊。

Sql Server的執行計畫

前一篇總結了sql server profiler,它主要用來監控資料庫,並跟蹤生成的sql語句。但是只拿到生成的sql語句沒有什麼用,我們可以利用這些sql語句,然後結合執行計畫來分析sql語句的效能問題,這才是我們的最終目的,那麼如何使用執行計畫呢?我準備從以下幾點來總結。如何啟動執行計畫 執行...

SQL Server 執行計畫

預讀 邏輯讀 物理讀的解釋 預讀 sql server查詢的時候會在記憶體中生成查詢計畫,但在同時會去硬碟上取估計的資料放入快取 邏輯讀 從快取中讀取資料 物理讀 當快取中也沒有的時候,就回去硬碟讀 檢視語句執 況 set statistics profile on set statistics i...

SQL Server 執行計畫

預讀 邏輯讀 物理讀的解釋 預讀 sql server查詢的時候會在記憶體中生成查詢計畫,但在同時會去硬碟上取估計的資料放入快取 邏輯讀 從快取中讀取資料 物理讀 當快取中也沒有的時候,就回去硬碟讀 檢視語句執 況 set statistics profile on set statistics i...