主要观点总结
本文主要介绍了在MySQL中遇到索引失效的场景,包括使用like语句、not like语句、not in语句、not exists语句等情况下索引失效的情况,以及其他如使用函数、表达式、隐式转换、不等于、is not null语句、or语句等情况下索引失效的场景。同时,也介绍了在执行sql语句时使用执行计划进行分析的方法,以及执行计划中的属性含义。
关键观点总结
关键观点1: MySQL索引失效的场景
包括使用like语句、not like语句、not in语句、not exists语句等情况下索引失效的情况。
关键观点2: 索引失效与数据库版本的关系
索引失效的情况可能与数据库版本有关。
关键观点3: 执行计划的分析
使用执行计划(EXPLAIN)分析sql是否正确地使用了索引,以及执行计划中的属性含义。
关键观点4: 访问类型(type属性)的说明
包括eq_ref和ref的解释,eq_ref是指每行数据都是通过主键或唯一索引与另一张表做 join,ref是指使用普通索引(不包括唯一索引)进行查找。
正文
'创建时间'
,
`update_time`
timestamp
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
COMMENT
'更新时间'
,
PRIMARY
KEY
(
`staff_id`
),
KEY
`id_no`
(
`id_no`
),
KEY
`union_idno_name_email`
(
`id_no`
,
`name`
,
`email`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=utf8
1. 使用 like 语句做模糊查询时,占位符 % 放在了最左边。比如我们查找 id_no 以 8933 结尾的员工:
select * from tb_staff where id_no like '%8933';
虽然 id_no 字段加了索引,但上面的 SQL 因为占位符在最左边,也不能走索引。
2. 使用 not like 语句,不能走索引。下面的 sql 使用 id_no 作为条件 ,不能走索引:
SELECT * FROM db_staff WHERE id_no NOT LIKE '120%';
3. 使用 not in 语句时,也不能走索引。举个例子 :
select * from tb_staff where id_no not in ('xxxx','yyyy');
4. 使用 not exists 语句时,也不能走索引。举个例子 :再建一张专门保存 staff_id 的表 db_staff_id
SELECT * FROM db_staff f WHERE NOT EXISTS (SELECT staff_id FROM db_staff_id a WHERE a.staff_id = f.staff_id);
面试官:not in 语句一定不能走索引吗?
我:不一定。如果 not in 后面跟的是主键,有可能会走索引。比如 not in 排除的值比较少,这种情况是会走索引的。
面试官:你还遇到过其他索引失效的场景吗?
我:还有几个场景,我再说一下:
5. 在条件语句中使用函数、表达式或隐式转换,比如下面的 sql:
--使用表达式
EXPLAIN SELECT * FROM db_staff WHERE staff_id + 1