mysql之索引失效场景

文章目录

    • 前言
    • 模糊查询失效
    • 联合索引失效
    • 函数导致索引失效
    • 隐式函数导致索引失效
    • 总结

前言

mysql目前是比较常用的一个数据库,我们在使用mysql查询数据的时候,为了提升效率,常常会给字段加上索引。但是在一些场景中,我们明明加了索引却没生效。这是因为一些条件或者场景会导致索引失效,今天我们就介绍下常见的索引失效的场景。

模糊查询失效

下面这种左前模糊查询查询会导致这个name上的索引失效

select * from t where name like '%张'

为什么会失效呢,本质原因还是,mysql去查找索引的时候,都是从左往后从第一个字段开始匹配的,但是你的第一个字段,最开始的字母是模糊查询,它就没匹配到对应的索引字段,所以会失效。

联合索引失效

假设我们有一个联合索引(a,b,c),这个联合索引的,只有你的条件是(a)(a,b)(a,b,c)的时候,才能生效,其他情况下(b)(b,c)等等,都会生效。原因也是。(a,b,c)是一个联合索引,在索引树上的节点存储的是(a,b,c)的值,走索引匹配的时候,一定的先匹配到a,在匹配到吧,最后再匹配到c,因为默认是从左往后按顺序放置的,所以,你不可能直接跳过a去匹配到b。

函数导致索引失效


mysql> select count(*) from tradelog where month(t_modified)=7;

上面这个sql会导致t_modified字段上的索引失效,至于为什么我们慢慢来说。首先,假如这个sql通过我们人来处理,肯定能走索引,我们人会解出t_modified的值,然后遍历索引树,取出这个对应的主键。但是,MySQL这没人这么智能,他是怎么处理的呢,它会把索引树上的所有索引的t_modified字段取出来,然后通过month函数处理下,然后拿处理的结果值去和7比较,最后得到结果主键值。

光这么,大家肯定不太容易理解,我再给大家举个例子,大家可能会更加清晰
下面这个语句会走索引

select * from t where age = 8

下面这个语句不会走索引

select * from t where age + 1 = 8

结合这个例子,大家是不是更容易理解上面的话,就是MySQL没有人这么智能,就是如果你把函数用到了字段这一边,他就蒙了,但是你如果用到了匹配结果值那边,它就会了。

隐式函数导致索引失效

select * from where age =10

上面这个sql,如果age是int类型的字段,那么加在age上面的索引便会失效,原因是mysql执行的时候会把它变为下面的sql

select * from where tovarchar(age) =10

首先说一下啊,这个tovarchar这个函数是我瞎写的,它就是代表这吧int类型变为varchar,具体mysql用的什么函数,我没仔细了解过,有兴趣的大家可以去MySQL官网,查询下官方文档,我这里只是为了方便理解,编造了一个函数。

同样的场景还有再表联合查询的时候

select * from table t  left join taver s  
on t.name = s.name

上面的场景中,即使表table 和表taver 的字段name是一个类型,但是两个表的编码方式不一样的话,也会导致索引失效,原因和上面的age那个例子差不多,这里不再赘述。

总结

索引的失效场景和条件很多,其本质原因,就是索引没有办法找到精确的值去匹配结果值,所以才会失效的(也就是我不知道我拿那一条索引值能匹配上这个结果值,所以才会扫描整个索引树)。

你可能感兴趣的:(mysql,mysql,数据库,sql)