《Microsoft Sql server 2008 Internal》读书笔记--第八章The Query Optimizer(1)
《Microsoft Sql server 2008 Interna》讀書筆記訂閱地址:
http://www.cnblogs.com/downmoon/category/230397.html/rss
《Microsoft Sql server 2008 Interna》索引目錄:
《Microsoft Sql server 2008 Internal》讀書筆記--目錄索引
SQL Server內置的查詢優化器負責對一個給定的SQL語句執行判斷作出最合理的查詢計劃。因為查詢優化器并沒有過多的內容展示于外界,因此不像SQL引擎 中的其他組件那樣為人熟知。第八章(The Query Optimizer)主要介紹查詢優化器及其工原理,本章讀完后,你應該會加深在較高層次的優化架構的理解,并熟知一個特定的查詢計劃為什么會被查詢優化 器所采用。此外,你應該能解決特定的案例,比如查詢優化器沒有選擇預期的執行計劃,以及什么因素影響了優化器的選擇。?
第八章是本書的另外核心技巧之一--查詢優化,它在底層數據存儲的基礎上,主要介紹對 已有的SQL語句或查詢進行針對性的測試和優化方法。這里有一些實用的技巧。本章分兩部分:第一部分介紹了查詢優化器的基本機制,包括它使用的高級架構及 如何定義每個計劃的一整套替代方案。第二部分查詢優化器的特定領域,以及它們如何適應Framwwork。例如“如何選擇索 引?”、“策略如何使用?”、“我如何理解更新計 劃?”等。本文先開個頭。
?■總覽?
對于一個簡單的查詢,基本的編譯“管道(pipeline)” 如下:
? 當一個查詢被編譯時,首先被解析為一個等價的樹表達式(tree representation)。對符合SQL語法的合法表達式,第二階段是執行一系列的(針對這個表達式的)驗證步驟,這個階段稱為綁定 (Binding),在此階段中,樹中的列和表與存儲在元數據中的列和表進行比較, 以確保列和表存在。這個階段對用戶是可見的。這一階段也對查詢作語義檢查,以確保查詢是有效的。比如確保綁定到GROUP BY操作的列是有效的。一旦查詢樹被綁定并被判定為一個有效的查詢,查詢優化器接管查詢,并開始評估不同可能的查詢計劃。查詢優化器執行查詢并返回給系統 執行。執行組件運行查詢,并返回查詢的結果。
SQL Server查詢優化器提供了一些附加內容,來擴展這個圖,以方便開發人員和DBA。比如優化計劃被緩存,因為它們對生產而言成本昂貴,且經常被重復執 行。當底層數據被充分改變時,舊的查詢計劃被重新編譯。SQL Server也支持T-SQL語言,這意味著在SQL引擎中,可以一次批量處理多個SQL語句請求。查詢優化器不考慮批編譯和工作和工作量分析,因此本章主要關注于單個查詢編譯。
?■樹格式(Tree Format)
?當你提交一個 SQL查詢到查詢處理器時,SQL字符串被解析為一個樹表達式,樹的每個節點代表了一個將要被執行的查詢操作。如下語句:
select?*?from?Customers?C?inner?join?Orders?O?on?C.cid=O.cid?where?C.data='2010-4-30'?可能的查詢如下:
?
?在整個編譯進程 中,查詢處理器實際上使用不同的查詢樹格式,例如查詢優化器執行的一個任務是根據預期結果的邏輯描述,轉換樹為一個能被執行的實際的物理計劃。最明顯的是 轉換一個邏輯join(比如inner join)為一個物理join(一個哈希join,merge join或嵌套循環join)。Most of the? tree formats are pretty close to each other。(這句邀月真不知如何翻譯?)
?■優化是什么
? 目前為止,我們討論的是轉換一個邏輯查詢為等價的物理查詢計劃。查詢優化器的另外一個任務是在眾多查詢計劃中找到一個高效的查詢計劃。
首先,這個計劃應該是看起來對每個SQL查詢而言都是一個“明顯的”最佳計劃,并且應該選擇盡可能快的計劃。實際上,查詢優化實際上是一個非常困難的問題。考慮下面的查詢:
inner?join?B?on?(A.a=B.b)
inner?join?C?on?(A.a=C.c)
inner?join?D?on?(A.a=D.d)
inner?join?E?on?(A.a=E.e)
inner?join?F?on?(A.a=F.f)
inner?join?G?on?(A.a=G.g)
inner?join?H?on?(A.a=H.h)
這 個查詢有多個可能的實現計劃,因為inner join可能被以不同的順序計算。事實上,查詢計劃的可能數量實際上比N!=N*(N-1)*……& amp;#8230;…要大得多。隨著查詢中表數量的增加,可供考慮的替代方案集迅速增加,變得計算機也無法計算。各種可能查詢計劃的存儲也成了一個問題。在一個32-bit的Intel x86機器中,SQL server實際上只能使用1.6G內存來編譯一個查詢,存儲每一種可能方案在內存是是不可能的。即便計算機能存儲各種替代計劃,用戶絕不會等待N久來等待系統枚舉各種可能的選擇。查詢優化器使用啟發式解決這個問題,并用統計來引導這些啟發,這正是本章要闡述的內容。
很多人會認為查詢優化器會對每一個給定的查詢而選擇一個“最佳”的查詢計劃。可實際上不可能所有的可能計劃都被篩選一遍,因此,快速選擇一個“足夠好的”計劃,更貼近于“查詢優化”的定義,這才是我們致力追求的目標。
■查詢優化器如何瀏覽查詢計劃?
查詢優化器使用框架(Framework)搜索和有效地比較各種可能的替代計劃, 這個框架允許SQL Server考慮復雜的,并不容易判斷的方式實現給定的查詢。持續地跟蹤所有可替代計劃并有效地找出一個計劃并非一件易事,SQL Server的搜索框架包括幾個組件,有助于它在有效而可靠地執行任務。
■ 規則(Rules)
查詢優化器是一個搜索框架,從一個給定的查詢樹,查詢優化器考慮將樹 從當前狀態轉化為一個不同的的等效狀態,而這個狀態將被存儲在內存中。在SQL Server使用的框架中,這個轉化是通過“規則(rule)",這些規則和你在學校里喜歡學習的工科數學定理非常類似。例如"A inner join B"和"B inner join A"結果肯定是一樣的,就像數學中的(2+1)和(1+2)的結果相等一樣。這些規則被匹配到樹模式,如果適于生成新的替代計劃,則規則被應用。這些規則 組成了查詢優化器工作的基礎,它們也有助于編碼某些必須的啟發式(以使其在合理的時間范圍內執行搜索)。
查詢優化器有各種不同的規則。規則啟發性地重寫一個查詢樹為一個新的形態(shape),被稱為“替代規則”, 考慮工科數學等式的規則被稱為“勘探規則(exploration rules)”。這些規則生成一些新的樹形態,但并不直接執行。轉換邏輯樹為將要被執行的物理樹的規則被稱為“ 實現規則(implementation rule)”,這些生成的物理替代計劃中的最佳者最終被查詢優化器輸出作為最終的查詢執行計劃。
查詢優化的更多原文,請查看:http://www.SQLserverInternal.com/companion/
■屬性?(Properties)
查詢框架用一種(針對規則而言)對它更易于工作的格式采集關于查詢樹的信息,這些信息稱為屬性(Properties)。它們從子樹(sub-tree) 中收集信息,這些信息有助于做決定什么樣的規則能被在一個更高的點上被處理,例如,一個在SQL Server中使用的屬性是一個在數據中(組成惟一鍵的)列的集合。看下面的一個例子:?
use?TestDbgo
IF?EXISTS?(SELECT?*?FROM?sys.tables????????
????????????WHERE?name?=?'Demotable')
????????DROP?TABLE?Demotable;
GO
CREATE?TABLE?[dbo].[Demotable](
????[Col1]?[int]?NOT?NULL,
????[Col2]?[int]?NULL,
????[Col3]?[int]?NULL
)
GO
insert?into?Demotable
select?1,3,4
union?all?select?2,?4,3
union?all?select??3,6,5
union?all?select?4,8,8
go
select?Col1,Col2,max(Col3)?from?Demotable?group?by?Col1,Col2
?
如果列(col1,col2)組成了惟一鍵,那么group by 就沒有必要了,看下列語句:
????????????WHERE?name?=?'Groupby')
????????DROP?TABLE?Groupby;
GO
CREATE?TABLE?[dbo].[Groupby](
????[Col1]?[int]?NOT?NULL,
????[Col2]?[int]?NULL,
????[Col3]?[int]?NULL
)
go
alter?table?groupby?add?constraint?uniquel?unique(col1,col2)
GO
insert?into?Groupby
select?1,3,4
union?all?select?2,?4,3
union?all?select??3,6,5
union?all?select?4,8,8
go
select?Col1,Col2,max(Col3)?from?Groupby?group?by?Col1,Col2
?SQL Server在優化期間采集N多屬性。正如其他編譯器所做的那樣,SQL Server查詢優化器采集有關每個查詢中引用的列的域限制信息。從預測、連接條件、分區信息中采集信息,檢查限制以知道這些預測如何被用于優化查詢。關 于純量屬性的一個有用的場景是矛盾探測(in contradiction detection)。查詢優化器能判定查詢是否不會返回任何行。
看下 面的例子 ,
?create?table?domaintable(col?int)go
select?*?from?domaintable?d1
inner?join?domaintable?d2?on?d1.col=d2.col
where?d1.col>5?and?d2.col<0
其實,最終的查詢計劃根本沒有引用表,取代原查詢的實際上是一個特殊的常量查詢,這個常量查詢沒有訪問存儲引擎。這是否是一個很聰明的選擇 呢?
與規則類似,屬性也有邏輯屬性與物理屬性之分。邏輯屬性包括像輸出列的集合,關鍵列,一個列是否能輸出null。這些被應用到所有等價的邏輯或物理計劃碎片。當這些勘探規則被評估時,結果查詢樹共享了同一邏輯屬性作為一個被規則使用的原始樹。物理屬性被定義到一個單個的計劃。每一個計劃操作器有一整套與之相關的物理屬性。一個常用的物理屬性是結果是否被排序。這個屬性將影響查詢優化器是否查找一個索引以交付預期的排序。另一個物理屬性是來自查詢表的列的集合。這將駕馭一些決定比如在查詢中一個次要的索引是否足夠充分返回需要的列,以及每個匹配和是否也需要一個基表瀏覽(look up)等等。
? 下一篇將通過一些實例繼續深入了解查詢優化器的替代存儲、計算序列等。
總結
以上是生活随笔為你收集整理的《Microsoft Sql server 2008 Internal》读书笔记--第八章The Query Optimizer(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MS932和Shift-JIS的差异
- 下一篇: VS 2008 Feature Pack