這篇文章主要和大家討論幾乎所有人都熟悉,但不少人又陌生的一條select語句。不知道大家有沒有想過到底是什么東西讓SQL Server能理解我們寫的select。這中間到底發(fā)生了什么,是不是有過沖動想去了解。至少我曾經(jīng)沖動想去了解,但當時主要在研究CLR以及WebFor
這篇文章主要和大家討論幾乎所有人都熟悉,但不少人又陌生的一條select語句。不知道大家有沒有想過到底是什么東西讓SQL Server能理解我們寫的select。這中間到底發(fā)生了什么,是不是有過沖動想去了解。至少我曾經(jīng)沖動想去了解,但當時主要在研究CLR以及WebForm相關知識。后來主要精力放在研究SQL Server內(nèi)部機制,今天就給大家介紹下這條語句。
一、范例數(shù)據(jù)庫腳本
createdatabase Test
go
alterdatabase Test set recovery simple
go
use Test
go
createtable Test
(
ID intidentity(1,1) primarykey,
[Name]varchar(64) notnulldefault'',
CreatedTime datetimenotnulldefaultgetdate()
)
insertinto Test([name]) values('xiaojun')
這個腳本就不介紹了,很簡單。
二、語句分析
select * from Test
簡單吧,本來嘛標題就是之簡單語句。下面開始分析這條語句吧,假設讀者已經(jīng)知道了SQL Server整體架構或者已經(jīng)閱讀過這個系列第一篇文章。當這條語句被可靠的傳遞到關系引擎中的命令分析器,接下來就發(fā)生了:
分析:
從語法庫中檢查T-SQL進行基本的語法檢查。如果語法出錯了,那整個語句就立即停止,提示用戶語法出錯,哪出錯。比如錯誤使用的關鍵字、列、表名等。如果語法沒有出錯,就會生成一個分析樹傳遞給下一個步驟。
綁定:
1、名字解析:檢查所有的對象在用戶的安全上下文中存在并可見。這個步驟很好理解主要是數(shù)據(jù)庫每個對象都有權限。如果登錄的賬號沒有相應權限,就結束這個步驟。
2、類型推導:確定解析樹中每個節(jié)點的最終類型。這個步驟主要是補充分析分析步驟中的分析樹,確定其最終的類型。不知道大家可想過為什么要到這一步才確定。為什么不在分析中確定呢?主要原因是效率,類型推導會消耗資源,沒有必要在沒有確定用戶對每個對象有權限的情況下確定。那為什么不直接先確定用戶對每個對象有權限再做分析呢。那是因為沒做分析的時候,系統(tǒng)無法知道具體有哪些對象。我又要說了,SQL Server的設計真的可以說是很精致的,連這樣的細節(jié)和資源消耗都考慮了。值得我們學習哦。
3、聚合綁定:確定哪些地方可以進行聚合。這個步驟主要和SQL中是否有聚合操作有關系。
4、組合綁定:將聚合綁定到正確的選擇列表中。這個步驟是把聚合操作與需要聚合的列綁定對應起來。
這兩步操作主要是由命令分析器完成,它最終得到分析樹,傳遞給SQL Server引擎中最復雜最有技術含量的組件,沒有之一,查詢優(yōu)化器。查詢優(yōu)化器功能概況起來很簡單,就是優(yōu)化SQL。具體優(yōu)化模型如下:
優(yōu)化:
1、檢查執(zhí)行計劃緩存中有沒有對應的執(zhí)行計劃。 如果沒有,繼續(xù)下面操作。如果有則使用緩存。SQL Server是根據(jù)SQL的哈希值比較的。想想為什么?
2、預優(yōu)化:查詢語句很簡單,開銷足夠小,直接結束優(yōu)化。比如沒有聯(lián)接的基本查詢。屬于零開銷,稱為普通計劃。比如我們這的select語句預優(yōu)化就搞定了。
3、階段0:檢驗基本規(guī)則,以及散列和嵌套聯(lián)接選項。這個計劃的開銷是否小于0.2,如果是,結束優(yōu)化。這里的0.2以及下面的1.0,這是SQL Server內(nèi)部的開銷值,僅供SQL Server系統(tǒng)內(nèi)部使用。
4、階段1:檢驗更多的規(guī)則,以及變換聯(lián)接的順序。如果開銷最小的計劃的開銷小于1.0,如果是,結束優(yōu)化。如果不是,繼續(xù)判斷。如果maxdop>0且這個系統(tǒng)是SMP系統(tǒng),以及最小開銷大于并行化的開銷臨界值,則使用并行計劃。比較并行計劃的開銷和最好的串行計劃的開銷,將開銷更小的計劃傳遞給階段2。
并行計劃是指優(yōu)化器根據(jù)情況,將恰當?shù)牟僮鞣鸱譃閿?shù)個可以同步運行的進程在不同的處理器上運行,需要多核支持。對于大數(shù)據(jù)量查詢可以提高效率。
maxdop是什么呢?這是SQL Server的一個高級配置。我們可以通過sp_configure查看。如下圖:
可能你直接運行sp_configure,看不到這個配置。主要是這是個高級配置項,默認不開啟。你運行以下語句后再運行sp_configure就能看到以上圖中信息。
sp_configure 'show advanced options',1
reconfigure
這里面的高級配置值,默認情況下不需要修改。必須你對SQL Server有較深理解,以及在修改前做好修改對整個SQL Server的影響的評估后才去改動。說說這個maxdop吧,這是說SQLServer在執(zhí)行并行計劃的最大處理器數(shù)目,0代表由SQL Server決定。否則就是按照用戶指定的最大并行度。因此上面的maxdop>0且這個系統(tǒng)是SMP系統(tǒng)的意思就是當用戶修改了這個配置項,那么執(zhí)行器在評估開銷時要優(yōu)先考慮用戶修改過的最大并行度小的系統(tǒng)開銷。SMP系統(tǒng)是對稱處理器體系結構,基于Intel處理器的服務器基本上都是SMP系統(tǒng)。在此不展開說。
不知道大家注意到?jīng)],我上面的圖查詢優(yōu)化器輸出的是較好的執(zhí)行計劃。想想為什么? 如果想查看優(yōu)化過程的內(nèi)部情況,可以使用一下sys.dm_exec_query_optimizer_info動態(tài)管理視圖。比如,下面演示證明我們這條select語句是屬于普通計劃。按照如下操作執(zhí)行:
dbcc freeproccache --清空執(zhí)行計劃緩存
select * from sys.dm_exec_query_optimizer_info where counter in('optimizations','trivial plan','search 0','search 1','search 2')
結果如下:
繼續(xù):
select * from Test
select * from sys.dm_exec_query_optimizer_info where counter in('optimizations','trivial plan','search 0','search 1','search 2')
結果如下:
發(fā)現(xiàn)了吧,trival plan類型計數(shù)+1,說明優(yōu)化器對select * from Test進行優(yōu)化時是普通計劃。
5、階段2:檢驗所有可能的計劃,并且選擇達到檢驗的時間限制時開銷最小的計劃。
執(zhí)行:這個計劃被調(diào)度執(zhí)行,這個涉及到SQLOS,不在本篇文章討論范圍,只要先簡單理解為交給CPU執(zhí)行。
三、結尾
其中這個語句還有很多地方可以分析,比如在這條語句執(zhí)行時,加鎖以及如何被調(diào)度執(zhí)行。這些還是希望在放在后面的章節(jié)中解釋。這篇文章主要是談到了SQ LServer如何對SQL進行解析優(yōu)化的。仔細研究,你會發(fā)現(xiàn)SQL Server的查詢優(yōu)化器做了很多優(yōu)化措施,當然其他數(shù)據(jù)庫也類似的組件。其實你會發(fā)現(xiàn)這些對于我們大部分開發(fā)人員都是屏蔽的。屏蔽是一種進步,java、.net的垃圾回收屏蔽了開發(fā)人員對內(nèi)存的管理,那SQL Server在這里屏蔽了什么呢,這需要研究數(shù)據(jù)庫歷史。只有研究歷史,才能站在一個較高的角度知道現(xiàn)在的數(shù)據(jù)庫為什么是現(xiàn)在的樣子。
今天分析就到此結束,文中如有描述不當?shù)牡胤剑瑲g迎指出。共同進步才是硬道理。
擦亮自己的眼睛去看SQLServer之簡單Insert
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com