MySQL一些索引失效的场景和原理
# 1、为什么is null 和 is not null 会导致索引失效?
主键索引无法存储null值,所以where的判断条件如果对字段进行了null值判断,将导致数据库放弃索引而进行全表查询。
但是普通索引,需要看数据库版本,数据量等,普通索引含有null的行也会走索引;数据库是否使用索引,还要看优化器如何做选择。
这里就说到 is null 和 is not null 走了索引:https://www.cnblogs.com/fanBlog/p/11938287.html
为什么主键索引列无法存储Null值?
因为主键索引是有序的。NULL值进入索引时,无法确定其应该放在哪里。(将索引列值进行建树,其中必然涉及到诸多的比较操作,null 值是不确定值无法比较,无法确定null出现在索引树的叶子节点位置。)
# 2、前导模糊查询不能利用索引
比如说 like '%XX'或者like '%XX%'
,
由于前面是模糊的,所以不能利用索引的顺序,必须一个个去找,看是否满足条件。这样会导致全索引扫描或者全表扫描。如果是这样的条件where code like 'A % '
,就可以查找CODE中A开头的CODE的位置,当碰到B开头的数据时,就可以停止查找了,因为后面的数据一定不满足要求。这样就可以利用索引了。
# 3、or 失效原因
or 不走索引的原因,可能是数据量太少,制定执行计划时发现全表更快,故MySQL没有走索引。
如果数据量大,可以看到MySQL语句的 or 字段还是可以走索引的。
通常情况下,用UNION
替换WHERE
子句中的OR
将会起到较好的效果,对索引列使用OR将造成全表扫描。
# 4、索引列使用函数
假如有 where month(t_modified)=7;
,t_modified 是一个datetime 字段
B+ 树中,它原来是按照 2021-08-23 15:06:24
这种格式有序排列的,它是没办法处理这个 7 的,于是就放弃了树搜索功能。
类似的,还有 类型的隐式转换、隐式字符编码转换 也是这个道理。