MySql--基于規(guī)則的優(yōu)化

具體細(xì)節(jié) 請(qǐng)去掘金購(gòu)買(mǎi)《MySQL 是怎樣運(yùn)行的:從根兒上理解 MySQL》

mysql會(huì)優(yōu)化我們的查詢條件進(jìn)行優(yōu)化赁遗,稱之為查詢重寫(xiě)

where子句必須放在group子句之前峭梳;而having子句必須在group子句之后

where子句只可以處理數(shù)據(jù)表中的數(shù)據(jù),having只能處理在group by子句中出現(xiàn)的字段样屠、select的列的字段或聚合函數(shù)處理過(guò)的列、外部查詢中的字段

mysql會(huì)化簡(jiǎn)我們的sql語(yǔ)句

  • 1.移除不必要的括號(hào)
  • 2.常量傳遞:a = 5 AND b > a--->a = 5 AND b > 5,用OR的時(shí)候這個(gè)條件就不能替換了
  • 3.等值傳遞:a = b and b = c and c = 5 --->a = 5 and b = 5 and c = 5
  • 4.移除沒(méi)用的條件:對(duì)于一些明顯永遠(yuǎn)為T(mén)RUE或者FALSE的表達(dá)式萝风,優(yōu)化器會(huì)移除掉它們
  • 5.表達(dá)式計(jì)算:a = 5 + 1-->a=6,函數(shù)是不會(huì)優(yōu)化的。
  • 6.HAVING子句和WHERE子句的合并:如果查詢語(yǔ)句中沒(méi)有出現(xiàn)諸如SUM、MAX等等的聚集函數(shù)以及GROUP BY子句顷扩,優(yōu)化器就把HAVING子句和WHERE子句合并起來(lái)。
  • 7.常量表檢測(cè):查詢的表中一條記錄沒(méi)有慰毅,或者只有一條記錄(不適合innodb)和使用主鍵等值匹配或者唯一二級(jí)索引列等值匹配(常量)作為搜索條件來(lái)查詢某個(gè)表
    優(yōu)化器在分析查詢語(yǔ)句時(shí)候隘截,先執(zhí)行常量表查詢,然后把查詢中涉及到該表的條件全部替換成常數(shù),最后再分析其余表的查詢成本
  • 8.外連接消除--(通過(guò)外連接加一個(gè)where語(yǔ)句限制鏈接的記錄不為null婶芭,可以把外連接消除东臀,進(jìn)而優(yōu)化器根據(jù)查詢成本選擇合適的驅(qū)動(dòng)表)內(nèi)連接的驅(qū)動(dòng)表和被驅(qū)動(dòng)表的位置可以相互轉(zhuǎn)換,而左外和右外的驅(qū)動(dòng)表和被驅(qū)動(dòng)表是固定的
  • 9.外連接和內(nèi)連接的本質(zhì)區(qū)別就是:對(duì)于外連接的驅(qū)動(dòng)表的記錄來(lái)說(shuō)犀农,如果無(wú)法在被驅(qū)動(dòng)表中找到匹配ON子句中的過(guò)濾條件的記錄惰赋,那么該記錄仍然會(huì)被加入到結(jié)果集中,對(duì)應(yīng)的被驅(qū)動(dòng)表記錄的各個(gè)字段使用NULL值填充呵哨;
    而內(nèi)連接的驅(qū)動(dòng)表的記錄如果無(wú)法在被驅(qū)動(dòng)表中找到匹配ON子句中的過(guò)濾條件的記錄赁濒,那么該記錄會(huì)被舍棄
  • 10.子查詢優(yōu)化

子查詢的二三事

  • 1.這種由子查詢結(jié)果集組成的表稱之為派生表。

按返回的結(jié)果集區(qū)分子查詢

  • 1.標(biāo)量子查詢:只返回一個(gè)單一值的子查詢
  • 2.行子查詢:就是返回一條記錄的子查詢孟害,不過(guò)這條記錄需要包含多個(gè)列(只包含一個(gè)列就成了標(biāo)量子查詢了)
  • 3.列子查詢:列子查詢自然就是查詢出一個(gè)列的數(shù)據(jù)嘍拒炎,不過(guò)這個(gè)列的數(shù)據(jù)需要包含多條記錄(只包含一條記錄就成了標(biāo)量子查詢了)。
  • 4.表子查詢:子查詢的結(jié)果既包含很多條記錄挨务,又包含很多個(gè)列

按與外層查詢關(guān)系來(lái)區(qū)分子查詢

  • 1.不相關(guān)子查詢:子查詢可以單獨(dú)運(yùn)行出結(jié)果击你,而不依賴于外層查詢的值
  • 2.相關(guān)子查詢:查詢的執(zhí)行需要依賴于外層查詢的值

子查詢?cè)诓紶柋磉_(dá)式中的使用

  • 1.操作數(shù) comparison_operator (子查詢):操作數(shù)可以是某個(gè)列名,或者是一個(gè)常量谎柄,或者是一個(gè)更復(fù)雜的表達(dá)式丁侄,甚至可以是另一個(gè)子查詢
    這里的子查詢只能是標(biāo)量子查詢或者行子查詢,也就是子查詢的結(jié)果只能返回一個(gè)單一的值或者只能是一條記錄

  • 2.[NOT] IN/ANY/SOME/ALL子查詢

  • 3.EXISTS子查詢

子查詢語(yǔ)法注意事項(xiàng)

  • 1.子查詢必須用小括號(hào)擴(kuò)起來(lái)谷誓。
  • 2.在SELECT子句中的子查詢必須是標(biāo)量子查詢绒障。
  • 3.在想要得到標(biāo)量子查詢或者行子查詢,但又不能保證子查詢的結(jié)果集只有一條記錄時(shí)捍歪,應(yīng)該使用LIMIT 1語(yǔ)句來(lái)限制記錄數(shù)量户辱。
  • 4.對(duì)于[NOT] IN/ANY/SOME/ALL子查詢來(lái)說(shuō),子查詢中不允許有LIMIT語(yǔ)句糙臼。
  • 5.ORDER BY子句無(wú)意義:子查詢的結(jié)果其實(shí)就相當(dāng)于一個(gè)集合庐镐,集合里的值排不排序一點(diǎn)兒都不重要
  • 6.DISTINCT語(yǔ)句無(wú)意義:集合里的值去不去重也沒(méi)啥意義
  • 7.在沒(méi)有聚集函數(shù)以及HAVING子句時(shí),GROUP BY子句就是個(gè)擺設(shè)
  • 8.不允許在一條語(yǔ)句中增刪改某個(gè)表的記錄時(shí)同時(shí)還對(duì)該表進(jìn)行子查詢

子查詢?cè)贛ySQL中是怎么執(zhí)行的

標(biāo)量子查詢变逃、行子查詢的執(zhí)行方式

  • 1.不相關(guān)標(biāo)量子查詢或者行子查詢來(lái)說(shuō),先執(zhí)行子查詢?cè)賵?zhí)行外層查詢必逆。
  • 2.對(duì)于相關(guān)的標(biāo)量子查詢或者行子查詢來(lái)說(shuō):先從外層查詢獲取一條記錄,然后從該記錄中找出子查詢涉及到的列
    揽乱,最后根據(jù)子查詢的查詢結(jié)果來(lái)檢測(cè)外層查詢WHERE子句的條件是否成立名眉,如果成立,就把外層查詢的那條記錄加入到結(jié)果集凰棉,否則就丟棄损拢。
  • 3.再次執(zhí)行第一步,獲取第二條外層查詢中的記錄撒犀,依次類推~

IN子查詢優(yōu)化

  • 1.對(duì)于不相關(guān)的IN子查詢:子查詢的結(jié)果集中的記錄條數(shù)很少福压,那么把子查詢和外層查詢分別看成兩個(gè)單獨(dú)的單表查詢
    如果子查詢的結(jié)果集的記錄條數(shù)很多掏秩,采用臨時(shí)表。
  • 2.臨時(shí)表中的記錄會(huì)被去重荆姆,如果子查詢結(jié)果集不是大的離譜蒙幻,可以基于內(nèi)存的使用Memory存儲(chǔ)引擎的臨時(shí)表,而且會(huì)為該表建立哈希索引
  • 3.一旦子查詢的結(jié)果集非常大胆筒,超過(guò)了系統(tǒng)變量tmp_table_size或者max_heap_table_size邮破,臨時(shí)表會(huì)轉(zhuǎn)而使用基于磁盤(pán)的存儲(chǔ)引擎來(lái)保存結(jié)果集中的記錄,索引類型也對(duì)應(yīng)轉(zhuǎn)變?yōu)锽+樹(shù)索引
  • 4.MySQL把這個(gè)將子查詢結(jié)果集中的記錄保存到臨時(shí)表的過(guò)程稱之為物化
  • 5.因此通過(guò)索引執(zhí)行IN語(yǔ)句判斷某個(gè)操作數(shù)在不在子查詢結(jié)果集中變得非称途龋快决乎,從而提升了子查詢語(yǔ)句的性能。

物化表轉(zhuǎn)連接

  • 1.最終in查詢?cè)谧優(yōu)槲锘淼臅r(shí)候整個(gè)查詢就變?yōu)閮?nèi)連接

將子查詢轉(zhuǎn)換為semi-join(半連接)

  • 1.可以能不進(jìn)行物化操作直接把子查詢轉(zhuǎn)換為連接
  • 2.對(duì)于s1表的某條記錄來(lái)說(shuō)派桩,我們只關(guān)心在s2表中是否存在與之匹配的記錄是否存在构诚,而不關(guān)心具體有多少條記錄與之匹配,最終的結(jié)果集中只保留s1表的記錄
  • 3.這樣的意思就是當(dāng)s1有記錄符合in中的子查詢即可铆惑,無(wú)需關(guān)心符合幾個(gè)in的參數(shù)范嘱。
  • 4.SELECT * FROM s1 WHERE key1 IN (SELECT common_field FROM s2 WHERE key3 = 'a');
    可以轉(zhuǎn)變(不是真正的轉(zhuǎn)變,只是為了表達(dá)意思)SELECT s1.* FROM s1 SEMI JOIN s2
    ON s1.key1 = s2.common_field
    WHERE key3 = 'a';

實(shí)現(xiàn)子查詢的方式

Table pullout (子查詢中的表上拉)

  • 1.當(dāng)子查詢的查詢列表處只有主鍵或者唯一索引列時(shí)员魏,可以直接把子查詢中的表上拉到外層查詢的FROM子句中丑蛤,并把子查詢中的搜索條件合并到外層查詢的搜索條件中
  • 2.因?yàn)檫@個(gè)時(shí)候可以確保子查詢只有一條記錄符合要求,因此可以拿到外部

DuplicateWeedout execution strategy (重復(fù)值消除)

  • 1.1表中的某條記錄可能在s2表中有多條匹配的記錄撕阎,所以該條記錄可能多次被添加到最后的結(jié)果集中受裹,為了消除重復(fù),我們可以建立一個(gè)臨時(shí)表

LooseScan execution strategy (松散索引掃描)

  • 1.SELECT * FROM s1 WHERE key3 IN (SELECT key1 FROM s2 WHERE key1 > 'a' AND key1 < 'b');
  • 2.在子查詢中虏束,對(duì)于s2表的訪問(wèn)可以使用到key1列的索引棉饶,而恰好子查詢的查詢列表處就是key1列,這樣在將該查詢轉(zhuǎn)換為半連接查詢后镇匀,可以將s2作為驅(qū)動(dòng)表執(zhí)行查詢的話
  • 3.掃描索引照藻,但只取值相同的記錄的第一條去做匹配操作的方式稱之為松散索引掃描。

Semi-join Materialization execution strategy

  • 1.我們之前介紹的先把外層查詢的IN子句中的不相關(guān)子查詢進(jìn)行物化汗侵,然后再進(jìn)行外層查詢的表和物化表的連接本質(zhì)上也算是一種semi-join幸缕,只不過(guò)由于物化表中沒(méi)有重復(fù)的記錄,所以可以直接將子查詢轉(zhuǎn)為連接查詢晰韵。

FirstMatch execution strategy (首次匹配)

  • 1.先取一條外層查詢的中的記錄发乔,然后到子查詢的表中尋找符合匹配條件的記錄,如果能找到一條雪猪,則將該外層查詢的記錄放入最終的結(jié)果集并且停止查找更多匹配的記錄栏尚,如果找不到則把該外層查詢的記錄丟棄掉;然后再開(kāi)始取下一條外層查詢中的記錄浪蹂,重復(fù)上邊這個(gè)過(guò)程

如何使用半連接

  • 1.原始語(yǔ)句:SELECT * FROM s1
    WHERE key1 IN (SELECT common_field FROM s2 WHERE s1.key3 = s2.key3);
  • 2.修改后的語(yǔ)句:ELECT s1.* FROM s1 SEMI JOIN s2
    ON s1.key1 = s2.common_field AND s1.key3 = s2.key3;
  • 3.這樣就可以使用我們上述說(shuō)道的幾種半連接查詢方式抵栈。
  • 4.對(duì)于相關(guān)子查詢 其并不是一個(gè)獨(dú)立的查詢,所以不能轉(zhuǎn)換為物化表來(lái)執(zhí)行查詢坤次。

semi-join的適用條件

  • 1.該子查詢必須是和IN語(yǔ)句組成的布爾表達(dá)式古劲,并且在外層查詢的WHERE或者ON子句中出現(xiàn)
  • 2.外層查詢也可以有其他的搜索條件,只不過(guò)和IN子查詢的搜索條件必須使用AND連接起來(lái)缰猴。
  • 3.該子查詢必須是一個(gè)單一的查詢产艾,不能是由若干查詢由UNION連接起來(lái)的形式。
  • 4.該子查詢不能包含GROUP BY或者HAVING語(yǔ)句或者聚集函數(shù)滑绒。

不適用于semi-join的情況

  • 1.外層查詢的WHERE條件中有其他搜索條件與IN子查詢組成的布爾表達(dá)式使用OR連接起來(lái)
  • 2.使用NOT IN而不是IN的情況
  • 3.在SELECT子句中的IN子查詢的情況
  • 4.子查詢中包含GROUP BY闷堡、HAVING或者聚集函數(shù)的情況
  • 4.子查詢中包含UNION的情況
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市疑故,隨后出現(xiàn)的幾起案子杠览,更是在濱河造成了極大的恐慌,老刑警劉巖纵势,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件踱阿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡钦铁,警方通過(guò)查閱死者的電腦和手機(jī)软舌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)牛曹,“玉大人佛点,你說(shuō)我怎么就攤上這事±璞龋” “怎么了超营?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)阅虫。 經(jīng)常有香客問(wèn)我糟描,道長(zhǎng),這世上最難降的妖魔是什么书妻? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任船响,我火速辦了婚禮,結(jié)果婚禮上躲履,老公的妹妹穿的比我還像新娘见间。我一直安慰自己,他們只是感情好工猜,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布米诉。 她就那樣靜靜地躺著,像睡著了一般篷帅。 火紅的嫁衣襯著肌膚如雪史侣。 梳的紋絲不亂的頭發(fā)上拴泌,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音惊橱,去河邊找鬼蚪腐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛税朴,可吹牛的內(nèi)容都是我干的回季。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼正林,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼泡一!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起觅廓,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鼻忠,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后杈绸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體粥烁,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年蝇棉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了讨阻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡篡殷,死狀恐怖钝吮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情板辽,我是刑警寧澤奇瘦,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站劲弦,受9級(jí)特大地震影響耳标,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜邑跪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一次坡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧画畅,春花似錦砸琅、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春诱篷,著一層夾襖步出監(jiān)牢的瞬間壶唤,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工棕所, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闸盔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓橙凳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親笑撞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子岛啸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

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

  • 轉(zhuǎn) # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    呂品?閱讀 9,739評(píng)論 0 44
  • 一、子查詢定義 定義: 子查詢?cè)试S把一個(gè)查詢嵌套在另一個(gè)查詢當(dāng)中茴肥。 子查詢坚踩,又叫內(nèi)部查詢,相對(duì)于內(nèi)部查詢瓤狐,包含內(nèi)部...
    我是強(qiáng)強(qiáng)閱讀 3,175評(píng)論 0 4
  • 介紹多表查詢等復(fù)雜SQL語(yǔ)句瞬铸。 關(guān)系數(shù)據(jù)庫(kù)的查詢結(jié)果都是一個(gè)結(jié)果表(也是關(guān)系) 集聚函數(shù) 基本語(yǔ)法 統(tǒng)計(jì)元組個(gè)數(shù)C...
    zealscott閱讀 835評(píng)論 0 0
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說(shuō)明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí),會(huì)觸發(fā)此異常础锐。 O...
    我想起個(gè)好名字閱讀 5,336評(píng)論 0 9
  • Cimarron挑了一張靠窗的桌子嗓节,窗外是一大片海,白色的皆警±剐晦澀的天,灰色的信姓。 ...
    岸幘尋青閱讀 139評(píng)論 0 0