一、创建表

  1. # 创建表
  2. create table test_index(
  3. c1 char(1) not null,
  4. c2 char(1) not null,
  5. c3 char(1) not null,
  6. c4 char(1) not null,
  7. c5 char(1) not null
  8. );
  9. # 创建索引
  10. alter table test_index add index index_c1234(c1,c2,c3,c4);
  11. create index xxx on table xxxx
  12. # 插入测试数据 这里打乱顺序方便后面排序
  13. insert into test_index values('1','1','1','1','1');
  14. insert into test_index values('5','5','5','5','5');
  15. insert into test_index values('2','2','2','2','2');
  16. insert into test_index values('4','4','4','4','4');
  17. insert into test_index values('3','3','3','3','3');

image.png

二、探索过程

从一道有趣的题目开始分析: 假设某个表有一个联合索引(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

  1. explain select * from test_index where c1='2' and c2='2' and c4>'1' and c3='2'

image.png

  • 一个值是4个字节,这里16个字节表示4个字段都使用了索引
  • type:range 这里是范围查询

接下来我们将c2去掉

  1. explain select * from test_index where c1='2' and c4>'1' and c3='2'

image.png

  • 显示只有四个字节即一个字段用到了缩影即c1。
  • 这是type:ref 即返回数据不唯一的等值查找

这里体现了索引的最左原则,即c2没有使用索引,c2之后的所有字段都不会使用索引,接下来再次验证这个理论
C1—>

  1. explain select * from test_index where c1 like '2'

image.png
C2—>

  1. explain select * from test_index where c2 like '2'

image.png
很明显c2没有走索引

B

  1. explain select * from test_index where c1='2' and c2='2' and c4='2' order by c3;

image.png
这里只有两个字段使用了索引,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

  1. explain select c1,c2,c3,c4 from test_index where c1='2' and c4='2' GROUP BY c3,c2

image.png
交换c3,c2的顺序

  1. explain select c1,c2,c3,c4 from test_index where c1='2' and c4='2' GROUP BY c2,c3

image.png
使用group by 一般先生成临时文件,再进行排序,但是字段顺序为c2,c3时,并没有用临时表进行排序,而是利用索引排序好的;当group by字段为c3,c2时,由于与索引字段顺序不一致,所以分组和排序并没有利用到索引。
由key_len长度确定,只有c1一个字段使用了索引。

D

  1. explain select * from test_index where c1='2' and c4='2' order by c2,c3

image.png

  1. explain select * from test_index where c1='2' order by c3,c2

image.png
排序时 order by不管先后顺序,都使用索引
由key_len长度确定,只有c1一个字段使用了索引

E

  1. explain select * from test_index where c1='2' and c2='2' and c5='2' order by c4,c2

image.png
c1,c2和排序使用了索引

  1. explain select * from test_index where c1='2' and c2='2' and c5='2' order by c5,c2

image.png
因为c5不是索引字段,所以这里不使用索引。