問題:
假設(shè)某個表有一個聯(lián)合索引(c1,c2,c3,c4)以下只能使用該聯(lián)合索引的c1,c2,c3部分
A where c1=x and c2=x and c4>x and c3=x
B where c1=x and c2=x and c4=x order by c3
C where c1=x and c4= x group by c3,c2
D where c1=? and c5=? order by c2,c3
E where c1=? and c2=? and c5=? order by c2,c3
一弊决、創(chuàng)建測試表和聯(lián)合索引
創(chuàng)建表t1刽宪,有c1到c5共5個字段,特別說明一下,字段類型都是定長char(1) 類型握联,并且非空苔严,字符集是utf8(與計算索引使用字節(jié)數(shù)有關(guān))。
create table t1(
c1 char(1) not null default '',
c2 char(1) not null default '',
c3 char(1) not null default '',
c4 char(1) not null default '',
c5 char(1) not null default ''
)engine myisam charset utf8;
?創(chuàng)建聯(lián)合索引:
alter table t1 add index c1234(c1,c2,c3,c4);
插入3條數(shù)據(jù):
insert into t1 values('a','b','c','d','e'),('A','b','c','d','e'),('a','B','c','d','e');
?二蟀瞧、分析
1沉颂、A選項
我們看解析A這條sql的結(jié)果条摸,與索引有關(guān)的主要是possible_keys,key,key_len這三項,possible_keys是指可能會用到的索引铸屉,key是當前sql使用到的索引钉蒲,key_len是索引的使用字節(jié)數(shù)。key的值是c1234表示聯(lián)合索引用上了彻坛,那是不是c1,c2,c3,c4全用上了咧顷啼,我們得從key_len分析一下。
? ? 因為字段類型是char(1)昌屉,字符集是utf8钙蒙,所以每個字段的key_len 是
1*3=3,key_len現(xiàn)在等于12表示c1,c2,c3,c4這四個字段都用上了索引间驮,(如果字段類型是null仪搔,那單個字段的索引字節(jié)數(shù)需要
+1,如果字段類型為非定長類型蜻牢,比如varchar烤咧,那字節(jié)數(shù)需要再 +2,這里方便理解抢呆,統(tǒng)一定義成了定長char)
2煮嫌、B選項
我們看到key=c1234,表示B使用了聯(lián)合索引抱虐,key_len=6表示有兩個字段使用了索引昌阿,這兩個字段就是C1和c2,這個sql里面有一個order
by c3恳邀,order by不能使用索引懦冰,但是卻利用了索引,為什么這么說咧谣沸,如果我們改成order by c5刷钢,看下面的:
? ? 與上面的結(jié)果對比,發(fā)現(xiàn)在Extra中的值使用了Using filesort乳附。Using
filesort表示在索引之外内地,需要額外進行外部的排序動作。因為c5的順序是沒有規(guī)律的赋除,所以需要對其進行一次排序阱缓,而在order by
c3的時候,c3其實在索引表里面已經(jīng)是排好序的了举农,不需要再排序荆针,所以說其實他利用上了索引。
3、C選項
key=c1234航背,表示B使用了聯(lián)合索引秸妥,key_len=3表示有1個字段使用了索引,這個字段就是C1沃粗,與B語句不一樣的是 Extra的值粥惧,C語句里面使用了臨時表(Using temporary) 和 排序(filesort),因為組合索引是需要按順序執(zhí)行的最盅,比如c1234組合索引突雪,要想在c2上使用索引,必須先在c1上使用索引涡贱,要想在c3上使用索引咏删,必須先在c2上使用索引,依此類推问词《胶回到B語句中,因為c2字段已經(jīng)使用了索引激挪,所以在order by c3的時候 c3其實在索引表里面已經(jīng)是排好序的了辰狡,不需要建臨時表,不需要再排序垄分,所以說其實他利用上了索引宛篇。
而C語句中,group by 的順序是先c3薄湿,再c2叫倍,在對c3進行g(shù)roup by的時候,c2字段上的索引并沒用使用豺瘤,所以索引在這里就斷了吆倦,只用上了c1一個字段的索引。
如果group by 的順序改成c2,c3坐求,會是什么樣蚕泽?
從結(jié)果中看沒有用到臨時表和filesort,因為c2,c3在索引表中本身就是有序的瞻赶。
4赛糟、D選項
從結(jié)果中看到key=c1234,表示B使用了聯(lián)合索引砸逊,key_len=3表示有一個字段使用了索引,即C1字段掌逛。而c2师逸,c3字段在order
by中是順序執(zhí)行,所以也利用了索引豆混。這里沒有使用filesort就是因為c2篓像,c3本身在索引表中就是有序的动知,所以不需要對其再排序。那如果反之员辩,先按c3排序盒粮,再按c2排序,會是什么情況奠滑,看下面:
從結(jié)果中看到使用了filesort丹皱,這里就無法合理的使用索引了。舉個例子來說宋税,好比中國下的省是有序的摊崭,如果按照先找國家再找省那自然是順序的,而如果反過來杰赛,先找省再找國家呢簸,那肯定是亂序的,自然也就不能利用索引了乏屯。
5根时、E選項
E語句c1和c2使用了索引,c3在order by中利用了索引辰晕。如果再反之啸箫,先按c3排序,再按c2排序會是什么情況伞芹?
order by c3,c2忘苛,按理說應(yīng)該使用filesort,但從結(jié)果中看并沒有使用唱较,這是為什么呢扎唾?注意仔細看查詢條件,c1='a'