在sqlserver中,有一個系統預存程序:sp_recompile,可以強制對訪問recompile【預存程序、觸發器、表、視圖】進行訪問的相關的sql語句進行重新編譯執行計畫!
如果 object 是預存程序或觸發器的名稱,那麼該預存程序或觸發器將在下次運行時重新編譯。如果 object 是表或視圖的名稱,那麼所有引用該表或視圖的預存程序都將在下次運行時重新編譯。
預存程序和觸發器所用的查詢只在編譯時間進行最佳化。對資料庫進行了索引或其它會影響資料庫統計的更改後,已編譯的預存程序和觸發器可能會失去效率。通過對作用於表上的預存程序和觸發器進行重新編譯,可以重新最佳化查詢。 Microsoft SQL Server 會在便利時自動對預存程序和觸發器進行重新編譯。
但該語句並不總是帶來正面的作用,有時會使得執行計畫變得更糟。原因進一步探究中..........???????
<<<<<<<<<<<<<<附錄>>>>>>>>>>>>>>>>
執行計畫的快取和重新使用
Microsoft SQL Server 2000 有用於儲存執行計畫和資料緩衝區的記憶體池。池內分配給執行計畫或資料緩衝區的百分比隨系統狀態動態波動。記憶體池中用於儲存執行計畫的部分稱為過程快取。
SQL Server 2000 執行計畫包含下面兩個主要組件:
- 查詢計劃
執行計畫的主體是一個重入的唯讀資料結構,可由任意數量的使用者使用。這稱為查詢計劃。查詢計劃中不儲存使用者環境。查詢計劃在記憶體中永遠不會有一個或兩個以上的複本:一個複本用於所有串列執行,一個複本用於所有並存執行。並行複本覆蓋所有的並存執行,與並存執行的並行度無關。
- 執行環境
每個正在執行查詢的使用者都有一個包含其執行專用資料(如參數值)的資料結構。該資料結構稱為執行環境。執行環境資料結構可以重新使用。如果使用者執行查詢而其中的一個結構未使用,將會用新使用者的環境重新初始化該結構。
在 SQL Server 2000 中執行任何 SQL 陳述式時,關聯式引擎將首先查看過程快取中是否有用於同一 SQL 陳述式的現有執行計畫。SQL Server 2000 重新使用所找到的任何現有計劃以節省重新編譯 SQL 陳述式的開銷。如果沒有現有執行計畫,則 SQL Server 2000 將為查詢產生新的執行計畫。
SQL Server 2000 有一個高效的演算法,可尋找用於任何特定 SQL 陳述式的現有執行計畫。在大多數系統中,這種掃描所使用的最小資源比通過重新使用現有計劃而不是編譯每個 SQL 陳述式所節省的資源要少。
該演算法將新的 SQL 陳述式與快取內現有的未用執行計畫相匹配,並要求所有的對象引用完全合法。例如,這兩個 SELECT 語句中的第一個語句與現有計劃不匹配,而第二個語句則匹配:
SELECT * FROM Employees
SELECT * FROM Northwind.dbo.Employees
執行計畫的老化
執行計畫產生後便駐留在過程快取中。只有當需要空間時,SQL Server 2000 才使舊的未用計劃從快取老化掉。每個查詢計劃和執行環境都有相關的成本因子,可表明編譯結構所需的費用。這些資料結構還有一個年齡欄位。對象每由串連引用一次,其年齡欄位便按編譯成本因子遞增。例如,如果一個查詢計劃的成本因子是 8 且被引用了兩次,它的年齡將變為 16。惰性寫入器進程定期掃描過程快取內的對象列表。惰性寫入器減少每個對象的年齡欄位,每掃描一次減少 1。在本例中,查詢計劃的年齡經過 16 次過程快取掃描後減為 0,除非其他使用者引用了該計劃。如果滿足下面三個條件,惰性寫入器進程將釋放對象:
- 記憶體管理器需要記憶體且所有可用記憶體都正在使用。
- 對象的年齡欄位是 0。
- 對象在當前沒有被串連引用。
因為每次引用對象時其年齡欄位都會增加,所以經常被引用的對象的年齡欄位不會減為 0,也不會從快取老化掉。不經常被引用的對象將很快滿足釋放條件,但是不會真被釋放,除非其它對象有記憶體需求。
重新編譯執行計畫
由於資料庫的新狀態,資料庫內的某些更改可能會導致執行計畫效率低下或不再有效。SQL Server 檢測這些使執行計畫無效的更改,並將計劃標記為無效。此後,必須為執行查詢的下一個串連重新編譯新的計劃。導致計劃無效的情況包括:
- 對查詢所引用的表或視圖進行任何結構更改(ALTER TABLE 和 ALTER VIEW)。
- 通過語句(如 UPDATE STATISTICS)顯式產生或者自動產生新的分發內容統計。
- 除去執行計畫所使用的索引。
- 顯式調用 sp_recompile。
- 對鍵的大量更改(其他使用者對由查詢引用的表使用 INSERT 或 DELETE 語句所產生的修改)。
- 對於帶觸發器的表,inserted 或 deleted 表內的行數顯著增長。