SQL Server效能調優之執行計畫深度剖析 第一節 淺析SQL執行的過程前言:在SQL Server中,執行計畫在查詢過程中其中關鍵性的作用,也是資料庫效能調優的重要方面,為最佳化提供了很多的資料依據。本系列文章前前後後會有幾十篇,將會對執行計畫進行深入淺出的講述,並且也會講述如何利用執行計畫進行資料庫調優。
為了使得大家更好的理解、消化這些知識,我會週期性就所寫內容進行線上的視頻講座,朋友們可以去參與這個小組:http://www.agilesharp.com/c/sqlprofiler.aspx
報名活動開始啦:http://www.agilesharp.com/Event.aspx/T-2
本篇文章的議題如下:
- 查詢計劃概述
- 查詢解析
- 查詢最佳化工具
- 查詢執行
- 查詢計劃的重用
查詢計劃概述
很多時候,當我們在使用sql server的時候,做的事情非常簡單:輸入sql語句,然後執行,最後擷取結果。下面,為了使得大家更加清楚的瞭解Sql server的內部機制,我們就重新來審視一個sql語句的執行。 把sql語句提到給了之後,資料庫會執行一系列的內部處理,我們大致的可將內部的處理按照執行的順序,劃分為兩個階段: 1. 發生在關聯式引擎中的操作 2. 發生在儲存引擎中的操作 在資料庫的關聯式引擎中,sql 的查詢語句會解析並且將解析的結果傳遞給後面的查詢最佳化工具,查詢最佳化工具負責產生執行計畫。之後,執行計畫(以二級制的格式)就會被傳遞到儲存引擎裡面,最後返回或更新底層的資料。 資料庫的儲存引擎會進行很多的操作,例如鎖定,索引的維護,事務的處理等。 因為本系列文章主要的剖析執行計畫,所以我們的關注點會放在關聯式引擎上面。 下面,我們就來稍微詳細的討論一個sql查詢語句的執行過程。
查詢解析
正如我們剛剛提到過:當把一個sql語句提交到了資料庫以後,sql語句最先會被傳入到關聯式引擎中。 當sql語句達到了關聯式引擎之後,首先要進行的操作就是檢查sql語句的格式是否正確。這個處理過程就是我們常說的“解析”過程。解析過程的結果就是產生一個解析樹,或者稱為查詢樹。查詢樹反映了一個查詢要執行的邏輯步驟,查詢樹的結構類似下面圖中所示: 其實從編譯原理的角度來看,這個解析過程就是文法和詞法的解析,最後產生文法樹。 有一點需要注意的就是:如果提交的sql語句不是一個資料動作陳述式(資料動作陳述式指Select,Insert,Update語句),那麼這個語句是不會被最佳化的。例如,如果提交的sql語句是建立一個資料表,那麼這個語句是不會被最佳化的,而是直接執行。 如果提交的資料動作陳述式,那麼之前由關聯式引擎建立的解析樹就會傳遞給
algebrizer
組件執行綁定過程。在這個綁定過程過程中,這個
algebrizer組件就會去檢查解析樹中的表名,列名是否都關聯到了資料庫中相應的表或對象的引用。 同時,
algebrizer組件還負責確定解析樹中的每個節點的類型是否和資料庫中對應的是否一致。
algebrizer組件以從下到上的方式開始遍曆樹,即,先從頁級節點開始,也就是列和常量。 綁定解析是一個非常重要的過程,在這個過程中還會識別出我們自己定義的一些別名。這個過程執行完成之後,就會產生一個二進位的“查詢處理樹”,這個樹會被傳遞給查詢最佳化工具。
查詢最佳化工具
查詢最佳化工具使用查詢處理樹和相關的統計資訊來產生一個執行計畫。 換句話說,查詢最佳化工具指出了如何最好的去執行提交的sql語句。查詢最佳化工具會決定是否可以採用索引來訪問資料,採用那種類型的join操作會更好(例如,儘管我們有時候在sql中寫的是Left Join,可能查詢最佳化工具在分析之後,在保證結果一樣的前提下,採用Inner Join)。 查詢最佳化工具是一個基本成本分析的最佳化器。這意味著它會嘗試為每個sql語句產生成本最低的執行計畫。 另外,我們來歸對於最佳化器所用到的統計資料進行簡要的解析。所謂的統計資料,就是在資料庫中描述列、索引相關資訊的資料,即資料的資料,或稱之為“中繼資料”。最佳化器就是結合統計資料和查詢處理樹來進行成本的估計的。 在預設的情況下,統計資訊是由資料庫內部自動的進行更新的(在調優的時候,可以手動的更新)。 需要提及的就是:表變數是沒有任何的統計資料的,也就是說,如果對錶變數中的資料進行查詢,最佳化器是不做任何的最佳化的。但是暫存資料表是有相應的統計資料的。 有一點需要注意的就是:上面的成本只是“估算”而已。一些複雜的語句可能會有很多個候選的執行計畫,在這種情況下,查詢最佳化工具不會分析所有的組合,而是找出一個接近理論最小值的一個執行計畫。計劃的成本表現為估計完成查詢所需的時間。最低估計成本不一定是最低的資源成本。
查詢執行
一旦執行計畫產生之後,操作就轉入儲存引擎中,這也是查詢真正被執行的地方,也是根據估計執行計畫 產生實際執行計畫的產所。
查詢計劃的重用
從之前的一些步驟可以看到:Sql Server產生一個
實際的執行計畫需要很多的步驟和很多的成本(執行計畫的過度編譯往往成為一個很大的效能問題),必須儘可能的重用執行計畫(如果後文不做特殊說明,執行計畫就指代“實際執行計畫”),所以,在資料庫中,一旦執行計畫產生之後,就被緩衝在了記憶體中(稱之為計劃緩衝)。 正如之前所提到的,當最佳化器產生了估計的執行計畫之後,計劃就會被傳遞給儲存引擎。其實在將估計的執行計畫傳給儲存引擎之前,查詢最佳化工具就去“計劃緩衝”中尋找與現在估計的執行計畫對應的實際執行計畫。如果找到了,那麼,查詢最佳化工具將會使用執行計畫傳進行後續操作。這樣就避免了重建實際的執行計畫。 一般而言,每個查詢的執行計畫都只儲存一個,除非查詢最佳化工具知道採用並存執行可以產生更好的效能,此時,並行查詢的執行計畫就被緩衝起來,也就是說:同一個查詢,在計劃緩衝中有兩個執行計畫。 執行計畫並不是永遠被儲存在記憶體中的。它們也是會到期的。SQL Server會基於最近最少使用的演算法來移除那些不常用的執行計畫。下面列出了執行計畫被移除的幾個條件: 1. 系統產生了記憶體壓力,需要更多的記憶體,此時迫使SQL Server釋放自己佔用的記憶體。 2. 記憶體中的執行計畫的最近使用次數為0. 3. 執行計畫沒有被現在的資料庫連接引用。
注:熟悉.NET的朋友,可以將之與.NET的記憶體回收機制類比理解。 今天就到這裡,下一篇,我們將對執行計畫進行更多的分析!
更多文章盡在:首發:IT創業互推平台
www.agilesharp.com 報名活動開始啦:http://www.agilesharp.com/Event.aspx/T-2