此博客的内容主要来源于尚硅谷的视频中,在此记录,以备以后自己查看。
drop table if exists test;
create table test(
id int primary key auto_increment,
c1 varchar(10),
c2 varchar(10),
c3 varchar(10),
c4 varchar(10),
c5 varchar(10)
) ENGINE=INNODB default CHARSET=utf8;
insert into test(c1,c2,c3,c4,c5) values('a1','a2','a3','a4','a5');
insert into test(c1,c2,c3,c4,c5) values('b1','b2','b3','b4','b5');
insert into test(c1,c2,c3,c4,c5) values('c1','c2','c3','c4','c5');
insert into test(c1,c2,c3,c4,c5) values('d1','d2','d3','d4','d5');
insert into test(c1,c2,c3,c4,c5) values('e1','e2','e3','e4','e5');
select * from test;
create index idx_test_c1234 on test(c1,c2,c3,c4);
show index from test;
explain select * from test where c1='a1' and c2='a2' and c3='a3' and c4='a4';
explain select * from test where c1='a1' and c3='a3' and c2='a2' and c4='a4';
explain select * from test where c1='a1' and c4='a4' and c3='a3' and c2='a2';
explain select * from test where c4='a4' and c3='a3' and c2='a2' and c1='a1';
分析:
结论:在执行常量等值查询的时候,改变索引列的顺序并不会更改explain的执行结果,因为mysql底层的优化器会进行优化,但是推荐按照索引顺序列编写sql语句。
explain select * from test where c1='a1' and c2='a2';
explain select * from test where c1='a1' and c2='a2' and c3>'a3' and c4='a4';
分析:
结论:范围索引右边索引列失效,但是范围当前位置(c3)的索引是有效的,从key_len=99可以证明。
explain select * from test where c1='a1' and c2='a2' and c4>'a4' and c3='a3';
结论:范围右边索引列失效,是由顺序的:c1,c2,c3,c4。如果c3有范围,则c4失效;如果c4有范围,则c4后面没有索引列,就没有失效的索引列,从而会使用全部索引。
explain select * from test where c1>'a1' and c2='a2' and c3='a3' and c4='a4';
# 覆盖索引
explain select c1,c2,c3,c4 from test where c1>'a1' and c2='a2' and c3='a3' and c4='a4';
分析:
结论:在最佳左前缀法则中,如果最左前列(带头大哥)的索引失效,则后面的索引都失效。
explain select * from test where c1='a1' and c2='a2' and c4='a4' order by c3;
explain select * from test where c1='a1' and c2='a2' order by c3;
分析:
explain select * from test where c1='a1' and c2='a2' order by c4;
explain select * from test where c1='a1' and c5='a5' order by c2,c3;
explain select * from test where c1='a1' and c5='a5' order by c3,c2;
explain select * from test where c1='a1' and c2='a2' order by c2,c3;
explain select * from test where c1='a1' and c2='a2' and c5='a5' order by c2,c3;
分析:
explain select * from test where c1='a1' and c2='a2' and c5='a5' order by c3,c2;
分析:
explain select * from test where c1='a1' and c4='a4' order by c2,c3;
分析:
explain select * from test where c1='a1' and c4='a4' order by c3,c2;
分析:
最佳左前缀法则。
在等值查询时,更改索引列顺序,并不会影响explain的执行结果,因为mysql底层会进行优化。
在使用order by时,注意索引顺序、常量,以及可能会导致Using filesort的情况。
group by容易产生Using temporary。
通俗理解口诀:
全值匹配我最爱,最左前缀要遵守;
带头大哥不能死,中间兄弟不能断;
索引列上少计算,范围之后全失效;
LIKE百分写最右,覆盖索引不写星;
不等空值还有or,索引失效要少用。