- 对索引使用左或左右模糊匹配
- 对索引使用函数(不过MySQL8.0之后索引特性增加了函数索引,可以针对函数计算后的值建立一个索引)
- 对索引进行表达式计算(如where id + 1 = 10,不过对应where id = 10 - 1却可以走索引)
- 对索引进行隐式类型转换。MySQL在遇到where一个字符类型的字段比如phone字段等于一串int整数12267会隐式地将字符串类型的索引转为int类型
- 验证MySQL会隐式地将字符串转为int整数
上图说明MySQL会隐式地将字符串“10”转换成10,否则,如果将9转换成“9”,两个数字字符串进行比较,从高位至低位比较,这时1 < 9则select结果为0才对
- 两个例子
例如执行select * from t_user where phone = 1300000001;
这个SQL,MySQL实际执行的是
select * from t_user where CAST(phone AS signed int) = 1300000001;
索引失效。
但是,对于int类型字段,出现where id = “1”,这时1用双引号标记,比如执行SQL
select * from t_user where id = "1";
这种情况下,MySQL实际执行的是
select * from t_user where id = CAST("1" AS signed int);
但是它并不是对索引字段进行的类型转换,而是对字符串参数“1”进行类型转换,索引不失效。
- 联合索引中不满足最左匹配原则。where字句中,联合索引定义的最左列不存在则联合索引失效。
另外,还会出现索引截断的问题。因为联合索引的B+树的排序规则是,先按照最左的第一列的字段排序,第一列数据相同时,才会按照第二列的字段排序。所以,为了尽可能地使用到联合索引中更多的列,我们where条件中的列必须是从联合索引中最左边的列开始连续的列(当然,其实有查询优化器的存在,只要最左边的列存在,则会走索引,至于使用到多少个字段,就要看where条件中是否包含其它列了)
- where字句中的or前后有一个条件列不是索引列,则会索引失效。而当都是索引列的时候,则会分别查询对两个字段走索引,将查询的结果合并在一起。