1.前导模糊查询不能利用索引(like '%XX'或者like '%XX%')
'A%'就可以正常使用索引
2.如果mysql估计使用全表扫描要比使用索引快,则不使用索引
3.OR前后存在非索引的列,索引失效
如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
4.普通索引的不等于不会走索引;如果是主键,则还是会走索引;如果是主键或索引是整数类型,则还是会走索引
5.组合索引最左前缀
如果组合索引为:(name,email)
name and email -- 使用索引
name -- 使用索引
email -- 不使用索引
6.is null可以使用索引,is not null无法使用索引
最好在设计表时设置NOT NULL约束,比如将INT类型的默认值设为0,将字符串默认值设为''。
7.计算、函数导致索引失效另外一种情况
- #使用到了索引
-
- explain select * from student_info where name like 'li%';
-
- #未使用索引,花费时间更久
-
- explain select * from student_info where LEFT(name,2)='li';
扩展:
如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
- #不会使用name的索引
-
- explain select * from student_info where name=123;
-
- #使用到索引
-
- explain select * from student_info where name='123';
如上,name字段是VARCAHR类型的,但是比较的值是INT类型的,name的值会被隐式的转换为INT类型再比较,中间相当于有一个将字符串转为INT类型的函数。这也相当于是函数导致的索引失效。
8.字符集不统一
统一使用utf8mb4( 5.5.3 版本以上支持 ) 兼容性更好,统一字符集可以避免由于字符集转换产生的乱码。不同的 字符集 进行比较前需要进行 转换 会造成索引失效。。