shanxiaoshuai 2020-08-29 18:44 采纳率: 0%
浏览 1681
已采纳

mysql复合索引中,使用like'xxx%'为什么不会使后续索引失效

最近在看索引优化相关的内容,有个知识点让我很疑惑。

举个例子:

create index index_c1c2c3 on table1(c1,c2,c3)

在表table1的c1,c2,c3三个字段创建复合索引,这个时候执行两条sql语句

1、select * from table1 where c1=a and c2>b and c3=c;

对该语句来说,因为c2列用了范围查询,导致复合索引只用了c1、c2两个字段,c3没用到。基于B+树的数据结构的话我觉得是没有问题。

2、select * from table1 where c1=a and c2 like 'c%' and c3=c;

对该语句来说,反而是三个索引都用到了,但是like的效果不是和范围查询一样吗?反正反B+树的数据结构来思考我是理解不了。各位大佬能帮忙解释一下吗?还是优化器在其中起作用了?

具体的实例如下,按B+树的结构来说,使用c2使用like后因为是范围查询,c3应该是无序的,怎么用索引呢?

图片

图片说明

图片说明

  • 写回答

3条回答 默认 最新

  • 新用户1 2021-03-27 13:48
    关注

    like KK%其实就是用到了索引下推优化

    对于辅助的联合索引(name,age,position),正常情况按照最左前缀原则,SELECT * FROM employees WHERE name like 'LiLei%' AND age = 22 AND position ='manager' 这种情况只会走name字段索引,因为根据name字段过滤完,得到的索引行里的age和position是无序的,无法很好的利用索引。

    在MySQL5.6之前的版本,这个查询只能在联合索引里匹配到名字是 'LiLei' 开头的索引,然后拿这些索引对应的主键逐个回表,到主键索引上找出相应的记录,再比对ageposition这两个字段的值是否符合。

    MySQL 5.6引入了索引下推优化,可以在索引遍历过程中,对索引中包含的所有字段先做判断,过滤掉不符合条件的记录之后再回表,可以有效的减少回表次数。使用了索引下推优化后,上面那个查询在联合索引里匹配到名字是 'LiLei' 开头的索引之后,同时还会在索引里过滤ageposition这两个字段,拿着过滤完剩下的索引对应的主键id再回表查整行数据。

    索引下推会减少回表次数,对于innodb引擎的表索引下推只能用于二级索引,innodb的主键索引(聚簇索引)树叶子节点上保存的是全行数据,所以这个时候索引下推并不会起到减少查询全行数据的效果。

    为什么范围查找Mysql没有用索引下推优化?

    估计应该是Mysql认为范围查找过滤的结果集过大,like KK% 在绝大多数情况来看,过滤后的结果集比较小,所以这里Mysql选择给 like KK% 用了索引下推优化,当然这也不是绝对的,有时like KK% 也不一定就会走索引下推 ,具体还要看MySQL分析各个索引使用成本,找出最优访问路径

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备
  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图2.0 版本点聚合中Marker的位置无法实时更新,如何解决呢?
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题