索引失效情况
左或者左右模糊匹配,like %xx,like %xx%
select * from student where name like '%三';
原因:B+是按照索引值有序排列,只能根据前缀比较来确定数据,一旦左边是模糊的,显然无法确定到底是哪个索引值
对索引字段使用函数
select * from student where length(id) = 16;
原因:因为索引保存的是原始字段的值,而不是函数处理过的值,一旦使用函数,显然无法再走索引
解决:可以把函数操作后的数据创建索引,然后再把函数操作作为条件,索引就生效了
对索引字段进行表达式计算
select * from student where id + 1 = 10;
原因:因为索引保存的是原始字段的值,而不是表达式计算过的值,显然无法再走索引
解决:把字段放在一边,select * from student where id = 10 - 1;
对索引隐式类型转换
select * from student where phone = 13888886666;
当字段为String,输入为数字,索引失效
原因:MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较,这样的类型转换,改变了值,与索引值无法匹配
组合索引非最左匹配
多个字段同时作为索引,最左侧的索引字段必须在条件中,否则就算其它字段在条件中,也不会走索引
原因:组合索引情况下,数据先按第一索引排序,第一索引相同再按第二索引排序,类推,所以如果条件中没有第一索引,匹配根本无法进行
注意:如果产生了索引截断,比如索引时三个字段a,b,c,条件中只有a,c,那么会进行索引下推,即会根据a字段走索引,拿到匹配的数据后就回表,读取数据后再比较c字段的值
where语句中使用or,or的一部分不是索引列
原因:or的含义就是两个满足一个就可以,那么就要两边都考虑,所以只有一边有索引是没有意义的
where条件中使用范围查询between,in,<,>
范围查询索引是否生效不是一刀切,过滤后的得到的数据量较小时会走索引,当过滤后得到的数据量较大,查找索引再回表,开销比直接查表还大,类似于重复性高的字段索引失效的原因