本文預(yù)計(jì)分為兩個(gè)部分:
(1)聯(lián)合索引部分的基礎(chǔ)知識(shí)
在這個(gè)部分绊起,我們溫習(xí)一下聯(lián)合索引的基礎(chǔ)
(2)聯(lián)合索引部分的實(shí)戰(zhàn)題
在這個(gè)部分掂碱,列舉幾個(gè)我認(rèn)為算是實(shí)戰(zhàn)中的代表題啊研,挑出來(lái)說(shuō)說(shuō)者祖。
正文
基礎(chǔ)
講聯(lián)合索引眶痰,一定要扯最左匹配!放心恍飘,我不扯有的沒(méi)的榨崩,幾句話懂個(gè)大概就行!
最左匹配
所謂最左原則指的就是如果你的 SQL 語(yǔ)句中用到了聯(lián)合索引中的最左邊的索引章母,那么這條 SQL 語(yǔ)句就可以利用這個(gè)聯(lián)合索引去進(jìn)行匹配母蛛,值得注意的是,當(dāng)遇到范圍查詢(>乳怎、<彩郊、between、like)就會(huì)停止匹配蚪缀。
假設(shè)焦辅,我們對(duì)(a,b)字段建立一個(gè)索引,也就是說(shuō)椿胯,你where后條件為
a=1a=1and b =2
是可以匹配索引的筷登。但是要注意的是~你執(zhí)行
b=2and a =1
也是能匹配到索引的,因?yàn)镸ysql有優(yōu)化器會(huì)自動(dòng)調(diào)整a,b的順序與索引順序一致哩盲。
相反的前方,你執(zhí)行
b=2
就匹配不到索引了。
而你對(duì)(a,b,c,d)建立索引,where后條件為
a =1andb =2andc >3andd =4
那么廉油,a,b,c三個(gè)字段能用到索引惠险,而d就匹配不到。因?yàn)橛龅搅朔秶樵儯?/p>
最左匹配的原理抒线?
假設(shè)班巩,我們對(duì)(a,b)字段建立索引,那么入下圖所示
如圖所示他們是按照a來(lái)進(jìn)行排序嘶炭,在a相等的情況下抱慌,才按b來(lái)排序逊桦。
因此,我們可以看到a是有序的1抑进,1强经,2,2寺渗,3匿情,3。而b是一種全局無(wú)序信殊,局部相對(duì)有序狀態(tài)!
什么意思呢炬称?
從全局來(lái)看,b的值為1涡拘,2玲躯,1,4鲸伴,1府蔗,2,是無(wú)序的汞窗,因此直接執(zhí)行b = 2這種查詢條件沒(méi)有辦法利用索引姓赤。
從局部來(lái)看,當(dāng)a的值確定的時(shí)候仲吏,b是有序的不铆。例如a = 1時(shí),b值為1裹唆,2是有序的狀態(tài)誓斥。當(dāng)a=2時(shí)候,b的值為1,4也是有序狀態(tài)许帐。
因此劳坑,你執(zhí)行a = 1 and b = 2是a,b字段能用到索引的。而你執(zhí)行a > 1 and b = 2時(shí)成畦,a字段能用到索引距芬,b字段用不到索引。因?yàn)閍的值此時(shí)是一個(gè)范圍循帐,不是固定的框仔,在這個(gè)范圍內(nèi)b值不是有序的,因此b字段用不上索引拄养。
綜上所示离斩,最左匹配原則,在遇到范圍查詢的時(shí)候,就會(huì)停止匹配跛梗。
實(shí)戰(zhàn)
OK寻馏,懂上面的基礎(chǔ),我們就可以開(kāi)始扯了~我舉了經(jīng)典的五大題型茄袖,看完基本就懂操软!
題型一
如果sql為
SELECT*FROMtableWHEREa =1andb =2andc =3;
如何建立索引?
如果此題回答為對(duì)(a,b,c)建立索引嘁锯,那都可以回去等通知了宪祥。
此題正確答法是,(a,b,c)或者(c,b,a)或者(b,a,c)都可以家乘,重點(diǎn)要的是將區(qū)分度高的字段放在前面蝗羊,區(qū)分度低的字段放后面。像性別仁锯、狀態(tài)這種字段區(qū)分度就很低耀找,我們一般放后面。
例如假設(shè)區(qū)分度由大到小為b,a,c业崖。那么我們就對(duì)(b,a,c)建立索引野芒。在執(zhí)行sql的時(shí)候,優(yōu)化器會(huì) 幫我們調(diào)整where后a,b,c的順序双炕,讓我們用上索引狞悲。
題型二
如果sql為
SELECT*FROMtableWHEREa >1andb =2;
如何建立索引?
如果此題回答為對(duì)(a,b)建立索引,那都可以回去等通知了妇斤。
此題正確答法是摇锋,對(duì)(b,a)建立索引。如果你建立的是(a,b)索引站超,那么只有a字段能用得上索引荸恕,畢竟最左匹配原則遇到范圍查詢就停止匹配。
如果對(duì)(b,a)建立索引那么兩個(gè)字段都能用上死相,優(yōu)化器會(huì)幫我們調(diào)整where后a,b的順序融求,讓我們用上索引。
題型三
如果sql為
SELECT*FROM`table`WHEREa >1andb =2andc >3;
如何建立索引?
此題回答也是不一定算撮,(b,a)或者(b,c)都可以生宛,要結(jié)合具體情況具體分析。
拓展一下
SELECT*FROM`table`WHEREa =1andb =2andc >3;
怎么建索引钮惠?嗯茅糜,大家一定都懂了!
題型四
SELECT*FROM`table`WHEREa =1ORDERBYb;
如何建立索引素挽?
這還需要想蔑赘?一看就是對(duì)(a,b)建索引,當(dāng)a = 1的時(shí)候,b相對(duì)有序缩赛,可以避免再次排序耙箍!
那么
SELECT*FROM`table`WHEREa >1ORDERBYb;
如何建立索引?
對(duì)(a)建立索引酥馍,因?yàn)閍的值是一個(gè)范圍辩昆,這個(gè)范圍內(nèi)b值是無(wú)序的,沒(méi)有必要對(duì)(a,b)建立索引旨袒。
拓展一下
SELECT*FROM`table`WHEREa =1ANDb =2ANDc >3ORDERBYc;
怎么建索引?
題型五
SELECT*FROM`table`WHEREaIN(1,2,3)andb >1;
如何建立索引汁针?
還是對(duì)(a,b)建立索引砚尽,因?yàn)镮N在這里可以視為等值引用施无,不會(huì)中止索引匹配,所以還是(a,b)!
拓展一下
SELECT*FROM`table`WHEREa =1ANDbIN(1,2,3)ANDc >3ORDERBYc;
如何建立索引必孤?此時(shí)c排序是用不到索引的猾骡。