MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。( 三 )

  • 节点 4 查询比较:节点4的第一个索引值的前缀符合林字,于是就读取该行数据,接着继续往右匹配,直到匹配不到前缀为林的索引值 。
  • 如果使用 name like '%林' 方式来查询,因为查询的结果可能是「陈林、张林、周林」等之类的,所以不知道从哪个索引值开始比较,于是就只能通过全表扫描的方式来查询 。
    想要更详细了解 InnoDB 的 B+ 树查询过程,可以看我写的这篇:B+ 树里的节点里存放的是什么呢?查询数据的过程又是怎样的?
    对索引使用函数有时候我们会用一些 MySQL 自带的函数来得到我们想要的结果,这时候要注意了,如果查询条件中对索引字段使用函数,就会导致索引失效 。
    比如下面这条语句查询条件中对 name 字段使用了 LENGTH 函数,执行计划中的 type=ALL,代表了全表扫描:
    // name 为二级索引select * from t_user where length(name)=6;
    MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。

    文章插图
    为什么对索引使用函数,就无法走索引了呢?
    【MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。】因为索引保存的是索引字段的原始值,而不是经过函数计算后的值,自然就没办法走索引了 。
    不过,从 MySQL 8.0 开始,索引特性增加了函数索引,即可以针对函数计算后的值建立一个索引,也就是说该索引的值是函数计算后的值,所以就可以通过扫描索引来查询数据 。
    举个例子,我通过下面这条语句,对 length(name) 的计算结果建立一个名为 idx_name_length 的索引 。
    alter table t_user add key idx_name_length ((length(name)));然后我再用下面这条查询语句,这时候就会走索引了 。
    MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。

    文章插图
    对索引进行表达式计算在查询条件中对索引进行表达式计算,也是无法走索引的 。
    比如,下面这条查询语句,执行计划中 type = ALL,说明是通过全表扫描的方式查询数据的:
    explain select * from t_user where id + 1 = 10;
    MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。

    文章插图
    但是,如果把查询语句的条件改成 where id= 10 - 1,这样就不是在索引字段进行表达式计算了,于是就可以走索引查询了 。
    MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。

    文章插图
    为什么对索引进行表达式计算,就无法走索引了呢?
    原因跟对索引使用函数差不多 。
    因为索引保存的是索引字段的原始值,而不是 id + 1 表达式计算后的值,所以无法走索引,只能通过把索引字段的取值都取出来,然后依次进行表达式的计算来进行条件判断,因此采用的就是全表扫描的方式 。
    有的同学可能会说,这种对索引进行简单的表达式计算,在代码特殊处理下,应该是可以做到索引扫描的,比方将id + 1 = 10 变成 id= 10 - 1 。
    是的,是能够实现,但是 MySQL 还是偷了这个懒,没有实现 。
    我的想法是,可能也是因为,表达式计算的情况多种多样,每种都要考虑的话,代码可能会很臃肿,所以干脆将这种索引失效的场景告诉程序员,让程序员自己保证在查询条件中不要对索引进行表达式计算 。
    对索引隐式类型转换如果索引字段是字符串类型,但是在条件查询中,输入的参数是整型的话,你会在执行计划的结果发现这条语句会走全表扫描 。
    我在原本的 t_user 表增加了 phone 字段,是二级索引且类型是 varchar 。
    然后我在条件查询中,用整型作为输入参数,此时执行计划中 type = ALL,所以是通过全表扫描来查询数据的 。

    经验总结扩展阅读