標籤:
概念簡介
我們平時所說的查詢在SQLServer 中主要有兩部分來實現:
- 編譯查詢,主要包括了五個環節(緩衝尋找、分析、代數化、最佳化、緩衝新計劃)
流程描述: 首先,在計畫快取中尋找是否包含新的查詢,如果包含則直接交由執行引擎來執行該緩衝計劃,跳過編譯階段。
其次,如果沒有匹配則執行分析階段(包括參數化、並將SQL文本轉化成邏輯樹狀結構作為下一個階段的輸入),
再次檢查緩衝後是否包含,包含則交給執行引擎,否則繼續下一步。
第三,代數化。
第四,最佳化並將新計劃交給執行引擎。
這裡需要有個概念的介紹:執行計畫緩衝,
SQL Server 有一個用於儲存執行計畫和資料緩衝區的記憶體池。池內分配給執行計畫或資料緩衝區的百分比隨系統狀態動態波動。
記憶體池中用於儲存執行計畫的部分稱為過程緩衝。
執行計畫緩衝主要包含了查詢計劃和執行內容。
2. 執行查詢計劃(產生執行計畫--產生查詢結果),在下一篇中介紹。
編譯和重新編譯
SQL Server 有一個高效的演算法,可尋找用於任何特定 SQL 陳述式的現有執行計畫。SQL Server 將重新使用找到的任何現有計劃,從而節省重新編譯 SQL 陳述式的開銷。如果沒有現有執行計畫,SQL Server 將為查詢產生新的執行計畫。由此我們要做的就是如何高效的應用執行計畫的緩衝,又在合適重新編譯執行計畫,來提高查詢效率,減少效能的損耗。
首先我們要知道什麼情況下會有重新編譯產生新的執行計畫,我簡單總結了幾種比較常見的情況:
1.使用WITH REPCOMPILE 或者調用sp_repcompile,將不會緩衝計劃。
2.架構的變更比如表或試圖中添加索引,增加或者刪除列等。
,當執行架構名稱不同的時候會引發重新編譯,執行計畫緩衝不能複用,這個問題需要開發人員注意,經常會有不自覺添加或者減少架構名稱的舉動。不僅會影響效能,當伺服器間行動程式碼時會引起太多問題,建議使用schema.object(dbo.ExcutionTest)這樣的統一規範。
如果是增刪索引的話,根據實際情況會產生完全不同的執行計畫。
建立索引後有表掃描變為了索引尋找,這部分內容我在叢集索引的章節已經有過介紹這裡就不詳細展開了。
3.SET選項,包括:ANSI_NULLS\ANSI_WARNINGS\CURSOR_CLOSE_ON_COMMIT_INPLICIT_TRANSACTIONS\ANSI_PADDING\QUOTED_IDENTIFIER,這些選項狀態的變化,會引起執行計畫的重新編譯。建議,盡量採用資料庫預設的設定,不要在預存程序中假如不必要的set選項。
4.根據計劃的最佳化程度:如果對鍵的大量更改(對由查詢引用的表使用 INSERT 、UPDATE或 DELETE 語句所產生的修改)。
分析、代數化和最佳化
1.分析,會將SQL文本轉換為邏輯樹狀結構,為每一個語句建立邏輯樹狀結構。
2.代數化,主要完成檢查語義是否正確。
同時還會完成三個任務:
- 名稱解析:查詢每個對象的名稱是否存在正確,範圍是否可見;
- 類型派生:在分析樹種各節點的欄位類型等,如錶鏈接後的欄位類型。
- 聚集綁定:根據文法判定聚集的實際操作在宿主查詢中。
- 分組綁定:驗證group by 文法是否正確(select 後面的非聚集列必須是group by後面的)。
3.最佳化
查詢最佳化是處理查詢中最複雜部分,這部分由系統自動完成,如果說前面的環節告訴我們“做什麼”,那麼最佳化器就是描述“如何做”,查詢最佳化工具希望儘可能選擇高效的執行計畫。這部分將在本系列最後做一個專題。詳細的闡述這裡現提出流程(簡化--探索--實現)。
總結:
本篇系統的介紹了編譯查詢的流程,以及產生緩衝、複用緩衝、重新編譯等具體內容。對於最佳化我們的T-SQL語句來說有不少值得注意的地方,執行計畫緩衝的命中越多相應的我們的查詢消耗也就越低,但是這種情況也不是絕對的。最後附加一個用於重新編譯的工具和命令的超連結,裡面有不少便於查詢分析執行計畫是否高效甚至存在問題功能和方法,http://www.cnblogs.com/wenBlog/p/4966991.html。
T-SQL效能調整(一)--編譯和重新編譯