导致 MySQL 索引失效的常见场景
- 联合索引不满足最左匹配原则
最左匹配原则是指以最左边的为起点字段查询可以使用联合索引,否则将不能使用联合索引。
假设联合索引为A+B+C,则能使用索引的为A+B+C、A+B、A+C。 - 模糊查询最前面的为不确定匹配字符
只有模糊匹配后面任意字符:like 'xx%'
可以使用索引 - 索引列参与了运算
如:explain select * from tname where id+1=1;
未使用索引 - 索引列使用了函数
如:explain select * from tname where ifnull(id,0)=1;
未使用索引 - 索引列存在类型转换
如果索引列存在类型转换,那么也不会走索引,比如 name 为字符串类型,而查询的时候设置了 int 类型的值就会导致索引失效 - 索引列使用 is not null 查询
当在查询中使用了 is not null 也会导致索引失效,而 is null 则会正常触发索引的
哪些情况不适合创建索引
- 不应该在字段比较长的字段上建立索引,因为会消耗大量的空间
- 对于频繁更新、插入的字段应该少建立索引,因为在修改和插入之后,数据库会去维护索引,会消耗资源
- 尽量少在无用字段上建立索引【where条件中用不到的字段】
- 表记录太少不应该创建索引
- 数据重复且分布平均的表字段不应该创建索引【选择性太低,例如性别、状态、真假值等字段】
- 参与列计算的列不适合建索引【保持列”干净”,比如from_unixtime(create_time) = ‘2022-05-29’就不能使用到索引,原因是b+树中存的都是数据表中的字段值,但进行检索时需要把所有元素都应用函数才能比较,显然成本太大,所以语句应该写成create_time = unix_timestamp(‘2022-05-29’)】
索引的优缺点
- 建立索引是要消耗一定的空间,况且在索引的维护上也会消耗资源