數(shù)據(jù)庫查詢優(yōu)化器

? 所謂查詢優(yōu)化璧瞬,目標是關(guān)系數(shù)據(jù)庫下或者 newSQL 的 SQL Server 層對 SQL 語句進行優(yōu)化栈暇,在不改變期望結(jié)果的情況下使得數(shù)據(jù)庫引擎計劃執(zhí)行時間最短麻裁。狹義的查詢優(yōu)化技術(shù)是指邏輯優(yōu)化物理優(yōu)化(在后面會細講),廣義上的查詢優(yōu)化技術(shù)包括從 SQL 語句輸入開始瞻鹏,對 SQL 語句的重寫悲立,內(nèi)部執(zhí)行算法的優(yōu)化鹿寨,并行優(yōu)化及分布式條件下的優(yōu)化新博,還包括了外部緩存機制對于查詢計劃及查詢結(jié)果的重用。
? 查詢優(yōu)化技術(shù)是數(shù)據(jù)庫領(lǐng)域十分重要的技術(shù)脚草,尤其在當前業(yè)務(wù)數(shù)據(jù)及業(yè)務(wù)請求規(guī)模不斷增長的情況下顯得尤為重要赫悄。這里從狹義的查詢優(yōu)化技術(shù)入手,從宏觀上講述查詢優(yōu)化器的架構(gòu)及各個模塊實現(xiàn)的主要功能任務(wù)馏慨,希望能夠?qū)Υ蠹伊私饧袄斫獠樵儍?yōu)化器有所幫助埂淮。

架構(gòu)


? SQL 語句經(jīng)過語法分析器生成語法分析樹,再通過查詢優(yōu)化器生成查詢樹及查詢計劃写隶,最后交由執(zhí)行器執(zhí)行倔撞。

架構(gòu)圖

語法分析器


語法分析

? 語法分析是指對用戶輸入的 SQL 語句進行判斷,糾正拼寫錯誤及語法錯誤慕趴。如:

Select name, class_name
from student S, course C, sc SC
where S.sno = SC.sno and C.cno = SC.cno and C.cno = 22;

?如果關(guān)鍵詞如 Select 拼寫錯誤痪蝇,或者語句不符合 Select_From_Where 語法規(guī)范,將在此步驟檢測出來冕房。

語義檢查

? 語義檢測負責判斷 SQL 語句中涉及的表及表中的屬性列是否存在躏啰,如果 SQL 所操作的目標表或者屬性列完全不存在那么后期的優(yōu)化也是徒勞無果的。比如在上面的 SQL 例子中耙册,將會判斷以下存儲對象或元數(shù)據(jù)是否存在给僵。

屬性列: name, class_name
相關(guān)表: student, course, sc

查詢優(yōu)化器


邏輯優(yōu)化

? 邏輯優(yōu)化簡單來說就是根據(jù)關(guān)系代數(shù)的等價變換規(guī)則進行查詢重寫。首先傳統(tǒng)關(guān)系代數(shù)運算符有并详拙、交帝际、差蔓同、積,對于 SQL 語句來說蹲诀,專有運算符有選擇牌柄、投影、連接侧甫、除珊佣。首先傳統(tǒng)運算符在 SQL 語句中的體現(xiàn)為:

  • 并 - union
Select * from R union Select * from S
  • 交 - not in(not in)
Select * from R where kr not in (
Select kr from R where kr not in (
Select ks from S))
  • 差 - not in
Select * from R where kr not in (Select ks from S)
  • 積 - 無條件join
Select R.* , S.* from R , S

專有運算符的 SQL 表現(xiàn):

  • 選擇 - condition
Select * from R where condition
  • 投影 - 屬性列
Select col_1,col_2+2 from R
  • 連接 - condition 中 join 或者等值連接
Select r.col_1,s.col_2 from R,S where condition
  • 除 - not exists(not exists)
Select Distinct r1.x from R,r1 where not exists (
Select S.y from S Where not exists (
Select * from R r2 where r2.x=r1.x and r2.y=S.y))

? 有了上述的運算符對應(yīng)關(guān)系, SQL 語句就可以使用關(guān)系代數(shù)的等價變換進行優(yōu)化披粟。這里有一些例子:

邏輯優(yōu)化舉例

物理優(yōu)化

? 物理優(yōu)化是與實際存儲相關(guān)的優(yōu)化階段咒锻。簡單來說就是通過代價模型對表級操作算法的選擇。
? 首先介紹代價模型守屉,學(xué)過計算機系統(tǒng)結(jié)構(gòu)的同學(xué)都知道惑艇,衡量計算機性能的重要指標就是相同任務(wù)或者指令的執(zhí)行時間。那么與之相似拇泛,一個執(zhí)行計劃的優(yōu)劣程度也可以使用時間來衡量滨巴。當然,數(shù)據(jù)庫查詢優(yōu)化的目標也是在盡可能短的時間返回期望的結(jié)果俺叭。所以代價模型的宏觀表達式為:總代價 = IO代價 + CPU代價

? 說回表級操作算法恭取,這里有以下3類:

  • 單表 ---> 掃描方式 : 全表掃描、索引掃描
  • 兩表 ---> 連接方式 : 嵌套循環(huán)連接熄守、歸并連接蜈垮、哈希連接
  • 多表 ---> 連接順序 : 動態(tài)規(guī)劃、啟發(fā)式裕照、貪心攒发、System R、遺傳算法

單表掃描

? 單表掃描的選擇主要通過選擇率來判斷晋南,也就是滿足條件的元組數(shù)(表中一行數(shù)據(jù))占總元組數(shù)的比例惠猿。同時在許多文章中,這里滿足條件的元祖數(shù)也稱為基數(shù)负间,有: 選擇率 = 基數(shù) / 總元組數(shù)偶妖。
? 比如在條件篩選過后可能只有 1/1000 的元組被選到,那么通過索引掃描的方式訪問整個表是很快的唉擂,但如果有 999/1000 的數(shù)據(jù)將會被篩選出來餐屎,那么通過全表掃描的方式或許更加有效。

兩表連接

? 傳統(tǒng)的兩表連接方法有嵌套循環(huán)連接玩祟、歸并連接及哈希連接腹缩。

  • 嵌套循環(huán)連接 : 相當于兩個for循環(huán),使用 A 表的一個元組去匹配 B 表的每一個元組,直到 A 表的所有元組都被訪問完全藏鹊。
  • 歸并連接 : 先將 B 表按照匹配的屬性列排序润讥,然后使用 A 表的每一個元組匹配 B 表的元組,一旦出現(xiàn)不匹配的情況下那么直接開始下一輪循環(huán)匹配(因為排過序盘寡,后續(xù)的元組也將不匹配)楚殿。
  • 哈希連接 : 先將 A 表所有元組對應(yīng)屬性列 hash ,然后將 B 表的每個元組對應(yīng)屬性列使用相同的散列方法 hash竿痰,若值相等則匹配脆粥。

多表連接順序

? 多表下是對各個表的連接順序進行選擇,比如 A影涉、B变隔、C 三個表,A蟹倾、B 較大匣缘,C 較小,那么 AB 先連接可能產(chǎn)生的中間結(jié)果會比較大鲜棠, 采用 BC-A 的連接順序可能先得到的中間結(jié)果就會比較小肌厨,既節(jié)省計算資源又節(jié)省存儲空間。常見的多表連接順序的選擇算法有動態(tài)規(guī)劃豁陆、啟發(fā)式柑爸、貪心、System R献联、遺傳算法竖配。PostgreSQl 中使用的算法為動態(tài)規(guī)劃及遺傳算法何址。

分布式查詢優(yōu)化


? 與單機的查詢優(yōu)化不同里逆,分布式情況下目標數(shù)據(jù)可能分布在不同的節(jié)點上。因此對于代價模型來說用爪,還需要加上數(shù)據(jù)傳輸的代價原押。同時由于分布式環(huán)境的復(fù)雜性,還要考慮到數(shù)據(jù)副本及底層數(shù)據(jù)庫引擎異構(gòu)(如關(guān)系型與 NoSQL )和異制(數(shù)據(jù)模型及數(shù)據(jù)結(jié)構(gòu)不相同偎血,比如文件型及 KV)的問題诸衔。

? 分布式環(huán)境下如果兩個要連接的表(A、B)在不同的節(jié)點上颇玷,這樣的情況下有兩種基本的連接算法:

  • 直接連接:直接將 B 表整個傳輸?shù)?A 表所在節(jié)點進行連接計算
  • 半連接:只是將 B 表要連接的屬性列傳輸?shù)?A 表所在節(jié)點進行連接計算笨农,計算完畢后傳輸回 B 表的節(jié)點篩選出匹配完成的元組

?很明顯,直接連接不適合目標表非常大的情況帖渠,但是半連接傳輸?shù)拇螖?shù)較多谒亦。

最后


? 以上旨在幫助大家宏觀認識數(shù)據(jù)庫查詢優(yōu)化器,對查詢優(yōu)化器架構(gòu)及各個模塊功能有大體認識。
? 以下是幾篇相關(guān)的經(jīng)典論文:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末份招,一起剝皮案震驚了整個濱河市切揭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锁摔,老刑警劉巖廓旬,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異谐腰,居然都是意外死亡孕豹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門十气,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巩步,“玉大人,你說我怎么就攤上這事桦踊∫我埃” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵籍胯,是天一觀的道長竟闪。 經(jīng)常有香客問我,道長杖狼,這世上最難降的妖魔是什么炼蛤? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮蝶涩,結(jié)果婚禮上理朋,老公的妹妹穿的比我還像新娘情臭。我一直安慰自己引几,他們只是感情好针贬,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布蔗崎。 她就那樣靜靜地躺著馒稍,像睡著了一般撕瞧。 火紅的嫁衣襯著肌膚如雪于样。 梳的紋絲不亂的頭發(fā)上屡律,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天挪圾,我揣著相機與錄音浅萧,去河邊找鬼。 笑死哲思,一個胖子當著我的面吹牛洼畅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棚赔,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼帝簇,長吁一口氣:“原來是場噩夢啊……” “哼务热!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起己儒,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤崎岂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后闪湾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冲甘,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年途样,在試婚紗的時候發(fā)現(xiàn)自己被綠了江醇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡何暇,死狀恐怖陶夜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情裆站,我是刑警寧澤条辟,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站宏胯,受9級特大地震影響羽嫡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肩袍,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一杭棵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧氛赐,春花似錦魂爪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蛙婴,卻和暖如春粗井,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背街图。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留懒构,地道東北人餐济。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像胆剧,于是被迫代替她去往敵國和親絮姆。 傳聞我的和親對象是個殘疾皇子醉冤,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容

  • ??前言: 我特別喜歡吃糯唧唧的東西蚁阳,像糕團啊,糯米燒賣啊之類的鸽照。最近在網(wǎng)上看到有糯米盒子賣螺捐!我當時就下單了,拿到的...
    大王子和小公主閱讀 384評論 0 4
  • 最有實感的矮燎,是身邊這個小娃娃定血。難怪有人說,最親的诞外,到最后終究是我生的澜沟,和生我的。血濃于水峡谊,亙古不變茫虽。 說起來是要陪...
    版納渝小魚閱讀 351評論 2 0
  • "我是凡人" 時空固執(zhí) 珍藏了你的影子 在太湖邊地 在大潮山里 我曾想 但愿 你不曾來 也不曾去吧 我依然是 習(xí)慣...
    清風草子閱讀 161評論 0 0