1.对索引字段做函数操作,可能会破坏索引值的有序性
优化器会决定放弃走树搜索功能。(即便逻辑大致相同),比如时间time本来是‘2018-7-1’ (datetime的类型),此时你用了month(time)=7,导致优化器不知道怎么走(看索引树就知道了,破坏了索引树同级节点的有序性)
mysql优化器处理比如 select * from tradelog where id
+ 1 = 10000 的时候会偷懒不走索引,即便这种条件写法不会破坏有序性,要手动改写成 where id = 10000 -1 才可以。
2.隐式类型转换
(字段是字符型条件是整型会导致索引失效)
mysql中,字符串和数字比较的时候的转换规则是字符串转数字。所以在mysql中,比如 select * from tradelog where tradeid=110717,其中tradeid是varchar类型,这里会被隐式转换成数值型导致索引失效
(字段是整数类型条件是字符串时,会走索引)
原因很简单,因为字符串和数字比较,是字符串转数字,比如select * from users where id='2'
补充:select 'a'=0,结果是1,因为无法转换成数字的字符串都会被转换成0来处理
3.隐式字符编码转换
比如两张表的id都是varchar类型的,但是表A的字符集是utf8,表B的是utf8mb4,此时连接两表的时候就会发生.隐式字符编码转换导致索引失效。比如select * from a,b where a.id=b.id
会发生字符集为utf8的字段强转为utf8m64,因为后者范围更大,此时转化的sql语句等同于
select * from a,b where convert(a.id USING utf8mb4) = b.id
解决方式有以下两种:
①一开始就用相同的字符集
②convert函数强转字符集