联合索引实战

联合索引使用规则

问题:html

假设某个表有一个联合索引(c1,c2,c3,c4)如下只能使用该联合索引的c1,c2,c3部分sql

A where c1=x and c2=x and c4>x and c3=xpost

B where c1=x and c2=x and c4=x order by c3测试

C where c1=x and c4= x group by c3,c2url

D where c1=? and c5=? order by c2,c33d

E where c1=? and c2=? and c5=? order by c2,c3htm

1、建立测试表和联合索引blog

建立表t1,有c1到c5共5个字段,特别说明一下,字段类型都是定长char(1) 类型,而且非空,字符集是utf8(与计算索引使用字节数有关)。排序

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;

 建立联合索引:索引

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'

 

原文地址:http://www.javashuo.com/article/p-hpwpmiyw-hy.html