- 1. 最左前缀法则
- 2.在索引列上做任何操作(计算,函数,(自动or手动)类型转换),会导致索引失效而转向全表扫描
- 3. 存储引擎不能使用索引中范围条件右边的列
- 4. 尽量使用覆盖索引(只访问索引的查询(索引列包含查询列)),减少select *
- 5.mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描
- 6.is null,is not null 也无法使用索引
- 7.like 以通配符开头(‘$abc’)mysql索引失效会变成全表扫描操作
- 8.字符串不加单引号,索引失效
- 9.少用or或in,用它查询时,mysql不一定使用索引,mysql内部优化器会根据检索比例,表大小等多个因素整体评估是否使用索引,详见范围查询优化
- 10.范围查询优化
- 索引使用总结:
1. 最左前缀法则
如果索引了多列,要遵守最做前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。
例如:联合索引(name,age)
select * from test where name='xx' and age =yy //索引生效select * from test where name='xx' //索引生效select * from test where age=yy //索引失效 :会根据索引字段按顺序一个一个比较 name字段去掉无法根据索引树查找

2.在索引列上做任何操作(计算,函数,(自动or手动)类型转换),会导致索引失效而转向全表扫描
explain select * from test where name='xx' //索引生效explain select * from test where left(name,3)='xx' //索引失效explain select * from employees where date(hire_time) ='2018-09-30' //索引失效->可优化为范围查找:explain select * from employees where hire_time>='2018-09-30 00:00:00' and hire_time <='2018-09-30 23:59:59' //索引生效
3. 存储引擎不能使用索引中范围条件右边的列
explain select * from employees where name='xx' and age=yy and position='zz' //索引生效使用的是name,age,position联合索引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.字符串不加单引号,索引失效
explain select * from employees where name='xx' //索引生效explain select * from employees where name= xx //索引失效
9.少用or或in,用它查询时,mysql不一定使用索引,mysql内部优化器会根据检索比例,表大小等多个因素整体评估是否使用索引,详见范围查询优化
10.范围查询优化
alter table 'employees' add index idx_age(age) using btree;explain select * from employees where age>=1 and age <=2000 //索引失效
没走索引原因:
mysql内部优化器会根据检索比例,表大小等多个因素整体评估是否使用索引。比如这个例子,可能是由于数据量查询过大导致优化器最终选择不走索引
优化方法:
可以将大的范围拆分成多个小范围
explain select * from employees where age>=1 and age<=1000;explain select * from employees where age>=1001 and age<=2000;
索引使用总结:

like kk%相当于=常量,%kk和%kk%相当于范围
