究极无敌细节版 Mysql索引( 七 )


究极无敌细节版 Mysql索引

文章插图

究极无敌细节版 Mysql索引

文章插图
常见索引失效的原因有
1.不满足最左前缀原则如果存在a,b,c的联合索引,select * from table where b=2 and a=1这种时候还是可能走联合索引的,mysql会优化语句,但是select * from table where b=1 and c=2是无法走联合索引的 , 因为b,c在b+树中整体无序
2.使用了select*使用select*需要回表,也许mysql优化器评估后觉得走非聚集索引,不如直接全表扫描
3.like查询左边有%以xxx开头是可以走索引的,因为是有序的,但是以xxx结尾和包含xxx是无法走索引的 。因为字符串的比较是从最左的字符开始比较的
4.order by 使用了联合索引中不存在的列,或者顺序不符合最左前缀匹配5.group by 使用了联合索引中不存在的列,或者顺序不符合最左前缀匹配6.不要在条件字段函数操作 , 注意隐式类型转换,小心隐式字符编码转换例如在A表的key1上建立索引,key1是int类型
6.1条件字段函数操作select xxx from A where key1+1<10 理论上说mysql可以进行优化,但是最好不要这么做,更不要select xxx from key1 where abs(key1)<10,mysql任何索引列上进行这些操作是会影响单调性的,直接无脑不走索引,分组排序也一样,select * from B left join A on B.key2 = A.key1+1 这个语句也一样(连表查询的原理见Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化)
6.2 注意隐式类型转换select * from A where key1>'10' 这个语句中key1是int类型,通样无法走索引,因为是将key1转化为字符串比较,还是将'10' 转化为数字比较昵,如果是前者那么key=9符合要求 , 如果是后者key1=9不符合要求 。
6.3 小心隐式字符编码转换如果两个表的字符集不同,那么做表连接查询的时候用不上关联字段的索引,比如字符集 utf8mb4 是 utf8 的超集,所以当这两个类型的字符串在做比较的时候,MySQL 内部的操作是,先把 utf8 字符串转成 utf8mb4 字符集,再做比较,相当于其中一列需要使用convert函数导致索引失效

推荐阅读