1. 最左前缀法则

如果索引了多列,要遵守最做前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。

例如:联合索引(name,age)

  1. select * from test where name='xx' and age =yy //索引生效
  2. select * from test where name='xx' //索引生效
  3. select * from test where age=yy //索引失效 :会根据索引字段按顺序一个一个比较 name字段去掉无法根据索引树查找

1626689901(1).jpg

2.在索引列上做任何操作(计算,函数,(自动or手动)类型转换),会导致索引失效而转向全表扫描

  1. explain select * from test where name='xx' //索引生效
  2. explain select * from test where left(name,3)='xx' //索引失效
  3. explain select * from employees where date(hire_time) ='2018-09-30' //索引失效
  4. ->可优化为范围查找:
  5. explain select * from employees where hire_time>='2018-09-30 00:00:00' and hire_time <='2018-09-30 23:59:59' //索引生效

3. 存储引擎不能使用索引中范围条件右边的列

  1. explain select * from employees where name='xx' and age=yy and position='zz' //索引生效使用的是name,age,position联合索引
  2. explain select * from employees where name='xx' and age >yy ane position ='zz' // 使用name,age索引 ,不是使用name,age,position索引

4. 尽量使用覆盖索引(只访问索引的查询(索引列包含查询列)),减少select *

5.mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描

6.is null,is not null 也无法使用索引

7.like 以通配符开头(‘$abc’)mysql索引失效会变成全表扫描操作

问题:解决like ‘%字符串%’索引不被使用的方法?

a) 使用覆盖索引,查询字段必须是建立覆盖索引字段

b) 如果不能使用覆盖索引则可能需要借助搜索引擎

8.字符串不加单引号,索引失效

  1. explain select * from employees where name='xx' //索引生效
  2. explain select * from employees where name= xx //索引失效

9.少用or或in,用它查询时,mysql不一定使用索引,mysql内部优化器会根据检索比例,表大小等多个因素整体评估是否使用索引,详见范围查询优化

10.范围查询优化

  1. alter table 'employees' add index idx_age(age) using btree;
  2. explain select * from employees where age>=1 and age <=2000 //索引失效

没走索引原因:

mysql内部优化器会根据检索比例,表大小等多个因素整体评估是否使用索引。比如这个例子,可能是由于数据量查询过大导致优化器最终选择不走索引

优化方法:

可以将大的范围拆分成多个小范围

  1. explain select * from employees where age>=1 and age<=1000;
  2. explain select * from employees where age>=1001 and age<=2000;

索引使用总结:

image-20210720171020884.png
like kk%相当于=常量,%kk和%kk%相当于范围