一、创建表
# 创建表
create table test_index(
c1 char(1) not null,
c2 char(1) not null,
c3 char(1) not null,
c4 char(1) not null,
c5 char(1) not null
);
# 创建索引
alter table test_index add index index_c1234(c1,c2,c3,c4);
create index xxx on table xxxx
# 插入测试数据 这里打乱顺序方便后面排序
insert into test_index values('1','1','1','1','1');
insert into test_index values('5','5','5','5','5');
insert into test_index values('2','2','2','2','2');
insert into test_index values('4','4','4','4','4');
insert into test_index values('3','3','3','3','3');
二、探索过程
从一道有趣的题目开始分析: 假设某个表有一个联合索引(c1,c2,c3,c4)以下选项哪些字段使用了该索引: 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
A
explain select * from test_index where c1='2' and c2='2' and c4>'1' and c3='2'
- 一个值是4个字节,这里16个字节表示4个字段都使用了索引
- type:range 这里是范围查询
接下来我们将c2去掉
explain select * from test_index where c1='2' and c4>'1' and c3='2'
- 显示只有四个字节即一个字段用到了缩影即c1。
- 这是type:ref 即返回数据不唯一的等值查找
这里体现了索引的最左原则,即c2没有使用索引,c2之后的所有字段都不会使用索引,接下来再次验证这个理论
C1—>
explain select * from test_index where c1 like '2'
C2—>
explain select * from test_index where c2 like '2'
B
explain select * from test_index where c1='2' and c2='2' and c4='2' order by c3;
这里只有两个字段使用了索引,Extra显示并没有使用临时表进行排序,说明排序是使用了索引的,但并没有计算在key_len值中,也没有起到连接c4的作用,说明索引到c3这里是断掉的。|
排序其实是利用联合索引直接完成了的,即:使用了c1234联合索引,就已经使得c1下c2,c2下c3,c3下c4是有序的了,所以实际是排序利用了索引,c3字段并没有使用该索引。
关于b选项,补充一下我的理解 因为前面的where使用了等值=来判断c1,c2,c4,那么where执行之后得到的结果中所有数据c1,c2都是相等的,这个时候order by c3其实等价于order by c1,c2,c3,所以c3排序不会导致filesort
C
explain select c1,c2,c3,c4 from test_index where c1='2' and c4='2' GROUP BY c3,c2
交换c3,c2的顺序
explain select c1,c2,c3,c4 from test_index where c1='2' and c4='2' GROUP BY c2,c3
使用group by 一般先生成临时文件,再进行排序,但是字段顺序为c2,c3时,并没有用临时表进行排序,而是利用索引排序好的;当group by字段为c3,c2时,由于与索引字段顺序不一致,所以分组和排序并没有利用到索引。
由key_len长度确定,只有c1一个字段使用了索引。
D
explain select * from test_index where c1='2' and c4='2' order by c2,c3
explain select * from test_index where c1='2' order by c3,c2
排序时 order by不管先后顺序,都使用索引
由key_len长度确定,只有c1一个字段使用了索引
E
explain select * from test_index where c1='2' and c2='2' and c5='2' order by c4,c2
c1,c2和排序使用了索引
explain select * from test_index where c1='2' and c2='2' and c5='2' order by c5,c2
因为c5不是索引字段,所以这里不使用索引。