SQL的查詢執(zhí)行順序解析

SQL語言不同于其他編程語言(如C++,Java)丘侠,最明顯的不同體現(xiàn)在處理代碼的順序上。在大多數(shù)編程語言中逐样,代碼按編碼順序被處理蜗字。但在SQL語言中打肝,第一個被處理的子句總數(shù)FROM子句,下面顯示了邏輯查詢處理的順序以及步驟的序號

(8)SELECT (9)DISTINCT <select_list> 
(1)FROM <left_table>
(3)<join_type> JOIN <right_table>
(2)ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH {CUBE|ROLLUP}
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>
(11)LIMIT <limit_number>

我們來具體分析查詢處理的各個階段

  • FROM:對FROM子句中的左表<left_table>和右表<right_table>執(zhí)行笛卡爾積挪捕,產(chǎn)生虛擬表VT1
  • ON:對虛擬表VT1應(yīng)用ON篩選粗梭,只有那些符合<join_condition>的行才被插入虛擬表VT2中
  • JOIN:如果指定了OUTER JOIN(如LEFT OUTER JOIN ,RIGTH OUTER JOIN)级零,那么保留表中未匹配的行作為外部行添加到虛擬表VT2中断医,產(chǎn)生虛擬表VT3。如果FROM子句含兩個以上表奏纪,則對上一個連接生成的結(jié)果表VT3和下一個表重復(fù)執(zhí)行步驟1~步驟3鉴嗤,直到處理完所有的表為止
  • WHERE: 對虛擬表VT3應(yīng)用VT3應(yīng)用WEHRE過濾條件,只有符合<where_conditon>的記錄才被插入虛擬表VT4中
  • GROUP BY:根據(jù)GROUP BY 子句中的列序调,對VT4中的記錄進(jìn)行分組操作醉锅,產(chǎn)生VT5
  • CUBE|ROLLUP:對表VT5進(jìn)行CUBE或ROLLUP操作,產(chǎn)生表VT6
  • HAVING:對虛擬表VT6應(yīng)用HAVING過濾器炕置,只有符合<having_condition>的記錄才被插入虛擬表VT7中
  • SELECT:選定指定的列荣挨,插入到虛擬表VT8中
  • DISTINCT:去除重復(fù)數(shù)據(jù)男韧,產(chǎn)生虛擬表VT9
  • ORDER BY:將虛擬表VT9中的記錄按照<order_by_list>進(jìn)行排序操作朴摊,產(chǎn)生虛擬表VT10
  • LIMIT:取出指定行的數(shù)據(jù),產(chǎn)生虛擬表VT11此虑,并返回給查詢用戶

第一步

首先我們創(chuàng)建好自己的倆個表


table.png

第二部來執(zhí)行我們需要的執(zhí)行語句

1.執(zhí)行笛卡爾積

第一部需要做的是對From子句前后的兩張表進(jìn)行笛卡爾積操作甚纲,也稱作交叉連接(Cross Join),生產(chǎn)虛擬表VT1朦前。如果FROM子句前的表中包含a行數(shù)據(jù)介杆,F(xiàn)rom子句后的表中包含b行數(shù)據(jù),那么虛擬表VT1中將包含a*b行數(shù)據(jù)韭寸。


image.png

2.應(yīng)用ON過濾器

SELECT查詢一共有3個過濾過程春哨,分別是ON,WHERE恩伺,HAVING赴背。ON是最先執(zhí)行的過濾過程。根據(jù)上一個步驟產(chǎn)生的虛擬表VT1晶渠,應(yīng)用ON進(jìn)行過濾


image.png

3.添加外部行

這一步只有在連接類型為OUTER JOIN時才發(fā)生凰荚,如LEFT OUTER JOIN,RIGHT OUTER JOIN褒脯,F(xiàn)ULL OUTER JOIN便瑟。雖然在大多數(shù)時候我們可以省略O(shè)UTER關(guān)鍵詞,但OUTER代表的就是外部行番川。LEFT OUTER JOIN把左表記為保留表到涂,RIGHT OUTER JOIN把右表記為保留表脊框,F(xiàn)ULL OUTER JOIN把左右表都記為保留表。添加外部行的工作就是在VT2表的基礎(chǔ)上添加保留表中被過濾條件過濾掉的數(shù)據(jù)养盗,非保留表的數(shù)據(jù)被賦予NULL值缚陷,最后生成虛擬表VT3


image.png

4.WEHRE條件過濾器

對上一個步驟產(chǎn)生的虛擬表VT3進(jìn)行WHERE條件過濾,只有符合<where_condition>的記錄才會輸出到虛擬表VT4中往核。

在當(dāng)前應(yīng)用WHERE過濾器時箫爷,有兩種過濾是不被允許的

由于數(shù)據(jù)還沒有分組,因此現(xiàn)在還不能再WHERE過濾器中使用where_condition=MIN(col)這類對統(tǒng)計的過濾
由于沒有進(jìn)行列的選取操作聂儒,因此在SELECT中使用列的別名也是不被允許的虎锚,如SELECT city as c FROM t WHERE c = "shanghai"是不允許出現(xiàn)的


image.png

5.進(jìn)行分組 Group By

image.png

6.應(yīng)用ROLLUP或CUBE

如果指定了ROLLUP選項(xiàng),那么將創(chuàng)建一個額外的記錄添加到虛擬表VT5的最后衩婚,并生成虛擬表VT6窜护。因?yàn)槲覀兊牟樵儾⑽从玫絉OLLUP,所以將跳過本步驟非春。

對于CUBE選項(xiàng)柱徙,MySQL數(shù)據(jù)庫雖然支持該關(guān)鍵字的解析,但是并未實(shí)現(xiàn)該功能奇昙。

7.HAVING條件過濾器

這是最后一個條件過濾器了护侮,之前已經(jīng)分別應(yīng)用了ON和WHERE過濾器。在該步驟中對于上一步產(chǎn)生的虛擬表應(yīng)用HAVING過濾器储耐,HAVING是對分組條件進(jìn)行過濾的篩序器羊初。


image.png

8.處理SELECT列表

雖然SELECT是查詢中最先被指定的部分,但是直到步驟8時才真正進(jìn)行處理什湘。在這一步中长赞,將SELECT中指定的列從上一步產(chǎn)生的虛擬表中選出


image.png

9.DISTINCT子句

如果在查詢中指定了DISTINCT子句,則會創(chuàng)建一張內(nèi)存臨時表(如果內(nèi)存中存放不下就放到磁盤上)闽撤。這張內(nèi)存臨時表的表結(jié)構(gòu)和上一步產(chǎn)生的虛擬表一樣得哆,不同的是對進(jìn)行DISTINCT操作的列增加了一個唯一索引,以此來去除重復(fù)數(shù)據(jù)哟旗。

由于在這個SQL查詢中未指定DISTINCT贩据,因此跳過本步驟。另外對使用了GROUP BY的查詢热幔,再使用DISTINCT是多余的乐设,因?yàn)橐呀?jīng)進(jìn)行分組,不會移除任何行

10.ORDER BY子句

image.png

11.LIMIT子句

在該步驟中應(yīng)用LIMIT子句绎巨,從上一步驟的虛擬表選出從指定位置開始的指定行數(shù)據(jù)近尚。對于沒有應(yīng)用ORDER BY的LIMIT子句,結(jié)果同樣可能是無序的场勤,因此LIMIT子句通常和ORDER BY子句一起使用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末戈锻,一起剝皮案震驚了整個濱河市歼跟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌格遭,老刑警劉巖哈街,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拒迅,居然都是意外死亡骚秦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門璧微,熙熙樓的掌柜王于貴愁眉苦臉地迎上來作箍,“玉大人,你說我怎么就攤上這事前硫“茫” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵屹电,是天一觀的道長阶剑。 經(jīng)常有香客問我,道長危号,這世上最難降的妖魔是什么牧愁? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮葱色,結(jié)果婚禮上递宅,老公的妹妹穿的比我還像新娘娘香。我一直安慰自己苍狰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布烘绽。 她就那樣靜靜地躺著淋昭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪安接。 梳的紋絲不亂的頭發(fā)上翔忽,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機(jī)與錄音盏檐,去河邊找鬼歇式。 笑死,一個胖子當(dāng)著我的面吹牛胡野,可吹牛的內(nèi)容都是我干的材失。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼硫豆,長吁一口氣:“原來是場噩夢啊……” “哼龙巨!你這毒婦竟也來了笼呆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤旨别,失蹤者是張志新(化名)和其女友劉穎诗赌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秸弛,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铭若,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了递览。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奥喻。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖非迹,靈堂內(nèi)的尸體忽然破棺而出环鲤,到底是詐尸還是另有隱情,我是刑警寧澤憎兽,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布冷离,位于F島的核電站,受9級特大地震影響纯命,放射性物質(zhì)發(fā)生泄漏西剥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一亿汞、第九天 我趴在偏房一處隱蔽的房頂上張望瞭空。 院中可真熱鬧,春花似錦疗我、人聲如沸咆畏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旧找。三九已至,卻和暖如春麦牺,著一層夾襖步出監(jiān)牢的瞬間钮蛛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工剖膳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留魏颓,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓吱晒,卻偏偏與公主長得像甸饱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子枕荞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

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