問題:sql
假設某個表有一個聯合索引(c1,c2,c3,c4)如下只能使用該聯合索引的c1,c2,c3部分測試
A where c1=x and c2=x and c4>x and c3=xspa
B where c1=x and c2=x and c4=x order by c33d
C where c1=x and c4= x group by c3,c2code
D where c1=? and c5=? order by c2,c3blog
E where c1=? and c2=? and c5=? order by c2,c3排序
1、建立測試表和聯合索引索引
建立表t1,有c1到c5共5個字段,特別說明一下,字段類型都是定長char(1) 類型,而且非空,字符集是utf8(與計算索引使用字節數有關)。table
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;
建立聯合索引:class
alter table t1 add index c1234(c1,c2,c3,c4);
插入3條數據:
insert into t1 values('a','b','c','d','e'),('A','b','c','d','e'),('a','B','c','d','e');
2、分析
一、A選項
咱們看解析A這條sql的結果,與索引有關的主要是possible_keys,key,key_len這三項,possible_keys是指可能會用到的索引,key是當前sql使用到的索引,key_len是索引的使用字節數。key的值是c1234表示聯合索引用上了,那是否是c1,c2,c3,c4全用上了咧,咱們得從key_len分析一下。
由於字段類型是char(1),字符集是utf8,因此每一個字段的key_len 是 1*3=3,key_len如今等於12表示c1,c2,c3,c4這四個字段都用上了索引,(若是字段類型是null,那單個字段的索引字節數須要 +1,若是字段類型爲非定長類型,好比varchar,那字節數須要再 +2,這裏方便理解,統必定義成了定長char)
二、B選項
咱們看到key=c1234,表示B使用了聯合索引,key_len=6表示有兩個字段使用了索引,這兩個字段就是C1和c2,這個sql裏面有一個order by c3,order by不能使用索引,可是卻利用了索引,爲何這麼說咧,若是咱們改爲order by c5,看下面的:
與上面的結果對比,發如今Extra中的值使用了Using filesort。Using filesort表示在索引以外,須要額外進行外部的排序動做。由於c5的順序是沒有規律的,因此須要對其進行一次排序,而在order by c3的時候,c3其實在索引表裏面已是排好序的了,不須要再排序,因此說其實他利用上了索引。
三、C選項
key=c1234,表示B使用了聯合索引,key_len=3表示有1個字段使用了索引,這個字段就是C1,與B語句不同的是 Extra的值,C語句裏面使用了臨時表(Using temporary) 和 排序(filesort),由於組合索引是須要按順序執行的,好比c1234組合索引,要想在c2上使用索引,必須先在c1上使用索引,要想在c3上使用索引,必須先在c2上使用索引,依此類推。回到B語句中,由於c2字段已經使用了索引,因此在order by c3的時候 c3其實在索引表裏面已是排好序的了,不須要建臨時表,不須要再排序,因此說其實他利用上了索引。
而C語句中,group by 的順序是先c3,再c2,在對c3進行group by的時候,c2字段上的索引並沒用使用,因此索引在這裏就斷了,只用上了c1一個字段的索引。
若是group by 的順序改爲c2,c3,會是什麼樣?
從結果中看沒有用到臨時表和filesort,由於c2,c3在索引表中自己就是有序的。
四、D選項
從結果中看到key=c1234,表示B使用了聯合索引,key_len=3表示有一個字段使用了索引,即C1字段。而c2,c3字段在order by中是順序執行,因此也利用了索引。這裏沒有使用filesort就是由於c2,c3自己在索引表中就是有序的,因此不須要對其再排序。那若是反之,先按c3排序,再按c2排序,會是什麼狀況,看下面:
從結果中看到使用了filesort,這裏就沒法合理的使用索引了。舉個例子來講,比如中國下的省是有序的,若是按照先找國家再找省那天然是順序的,而若是反過來,先找省再找國家,那確定是亂序的,天然也就不能利用索引了。
五、E選項
E語句c1和c2使用了索引,c3在order by中利用了索引。若是再反之,先按c3排序,再按c2排序會是什麼狀況?
order by c3,c2,按理說應該使用filesort,但從結果中看並無使用,這是爲何呢?注意仔細看查詢條件,c1='a' and c2='b',那麼在全部查詢出來的行中,c2其實只有一個值,永遠等於'b',也就是說c2是一個常量,也就意味着order by c3,c2 至關於對c3和一個常量排序,能夠寫成這樣order by c3,'b',因此order by c3,'b'說白了仍是對c3進行排序,由於後面的‘b’永遠都是同樣的,他是一個常量,而常量對排序並無影響,能夠忽略不計,所以這裏並無使用filesort。
若是將條件c2='b'去掉,那天然就要用到filesort了,看下面的結果: