SQL Server 執行計畫緩衝(1)
概述
瞭解執行計畫對資料庫效能分析很重要,其中涉及到了語句效能分析與儲存,這也是寫這篇文章的目的,在瞭解執行計畫之前先要瞭解一些基礎知識,所以文章前面會講一些概念,學起來會比較枯燥,但是這些基礎知識非常重要。
基礎概念
SQL Server 有一個用於儲存執行計畫和資料緩衝區的記憶體池。池內分配給執行計畫或資料緩衝區的百分比隨系統狀態動態波動。記憶體池中用於儲存執行計畫的部分稱為過程緩衝。
SQL Server 執行計畫包含下列主要組件:
查詢計劃
執行計畫的主體是一個重入的唯讀資料結構,可由任意數量的使用者使用。這稱為查詢計劃。查詢計劃中不儲存使用者上下文。記憶體中查詢計劃副本永遠不超過兩個:一個副本用於所有的串列執行,另一個用於所有的並存執行。並行副本覆蓋所有的並存執行,與並存執行的並行度無關。
執行內容
每個正在執行查詢的使用者都有一個包含其執行專用資料(如參數值)的資料結構。此資料結構稱為執行內容。執行內容資料結構可以重新使用。如果使用者執行查詢而其中的一個結構未使用,將會用新使用者的上下文重新初始化該結構。
怎樣緩衝執行計畫
SQL Server 有一個高效的演算法,可尋找用於任何特定 SQL 陳述式的現有執行計畫。在 SQL Server 中執行任何 SQL 陳述式時,關聯式引擎將首先查看過程緩衝中是否有用於同一 SQL 陳述式的現有執行計畫。SQL Server 將重新使用找到的任何現有計劃,從而節省重新編譯 SQL 陳述式的開銷。如果沒有現有執行計畫,SQL Server 將為查詢產生新的執行計畫。
SQL Server自動刪除執行計畫
什麼情況下會刪除執行計畫
在沒有人工手動清除緩衝的情況下,如果出現記憶體不足的情況下SQL Server會自動清除一部分沒被利用到的緩衝計劃。
所有緩衝的最大大小取決於max server memory的大小。
怎樣判斷需要刪除的執行計畫
如果存在記憶體不足的情況,資料庫引擎將使用基於開銷的方法來確定從過程緩衝中刪除哪些執行計畫。怎樣確定一個執行計畫的開銷呢,對於一個第一次執行的執行計畫SQL Server將它的開銷值設為0,被多次執行過的執行計畫SQL Server將它的開銷值設定為原始編譯開銷,所以資料庫引擎會重複檢查每個執行計畫的狀態並將刪除當前開銷為零的執行計畫。如果存在記憶體不足的情況,當前開銷為零的執行計畫不會自動被刪除,而只有在資料庫引擎檢查該執行計畫並發現其當前開銷為零時,才會刪除該計劃。當檢查執行計畫時,如果當前沒有查詢使用該計劃,則資料庫引擎將降低當前開銷以將其推向零。
資料庫引擎會重複檢查執行計畫,直至刪除了足夠多的執行計畫,以滿足記憶體需求為止。如果存在記憶體不足的情況,執行計畫可多次對其開銷進行增加或降低。如果記憶體不足的情況已經消失,資料庫引擎將不再降低未使用執行計畫的當前開銷,並且所有執行計畫都將保留在過程緩衝中,即使其開銷為零也是如此。
重新編譯執行計畫
根據資料庫新狀態的不同,資料庫中的某些更改可能導致執行計畫效率降低或無效。SQL Server 將檢測到使執行計畫無效的更改,並將計劃標記為無效。此後,必須為執行查詢的下一個串連重新編譯新的計劃。導致計劃無效的情況包括:
- 對查詢所引用的表或視圖變更(ALTER TABLE 和 ALTER VIEW)。
- 對執行計畫所使用的任何索引變更。
- 對執行計畫所使用的統計資訊進行更新,這些更新可能是從語句(如 UPDATE STATISTICS)中顯式產生,也可能是自動產生的。
- 刪除執行計畫所使用的索引。
- 顯式調用 sp_recompile。
- 對鍵的大量更改(其他使用者對由查詢引用的表使用 INSERT 或 DELETE 語句所產生的修改)。
- 對於帶觸發器的表,插入的或刪除的表內的行數顯著增長。
- 使用 WITH RECOMPILE 選項執行預存程序。