为了账号安全,请及时绑定邮箱和手机立即绑定

Innodb覆盖索引的几个疑问

Innodb覆盖索引的几个疑问

HUX布斯 2019-04-27 22:14:28
对InnoDB覆盖索引的疑问首先,我对覆盖索引的了解是,如果创建了二级索引后,要想做到覆盖索引,那么你select的列就要被你的索引所覆盖比如,当我创建一个二级索引idx_name_age(name,age)对selectnamefromuserwherename="Jhon";语句,自然就可以做到覆盖索引这样就不用再回表走聚簇索引了但是当我selectidfromuserwhereid=1;时,这个用到了主键索引,也就是会直接走聚簇索引,既然走聚簇索引的话,B+Tree的叶子节点是包含所有列的,那我认为select*fromuserwhereid=1;也是一样的但explain的分析结果发现selectidfromuserwhereid=1;是主键索引,并且做到了覆盖索引但是select*fromuserwhereid=1;虽然是主键索引,但却不是覆盖索引,这是为啥?
查看完整描述

2 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

可以这样理解吧,主键索引,那么就是按照主键排序,组成B+树,例如你的id,那么主键索引的索引键就是id,而剩余的行数据只是跟在索引键后面而形成聚簇表,主键索引并没有对除主键以外的数据进行索引;那么,从覆盖索引的概念:select语句所有要查询的列都必须是索引键,也就是说对于主键索引,覆盖索引应该是只查主键,这样主键索引才起到“覆盖”的作用;而select*是需要把整行数据都查出来,并不只是查询主键了。
                            
查看完整回答
反对 回复 2019-04-27
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

对于覆盖索引,有这样一个定义:
一个索引包含所有需要查询的字段的值,我们就称之为“覆盖索引”。
也就是说,覆盖索引并不是实质意义上的索引。只要一个索引满足部分SQL的查询条件,我们就认为这个索引是覆盖索引。其实就是给索引起了个别名。就像idx_name_age是一个索引,它也是你写的SQL的覆盖索引。
此外,为什么会出现覆盖索引呢?对于InnoDB而言,索引存放的是所有字段的值,如果一个查询需要的字段刚好是这个索引的所有字段,那么此次查询很可能就不用去库查询行数据,减少IO,我们也就认为这个索引是覆盖索引了。
回到题主的问题,为什么是主键索引,不是覆盖索引,就是因为查询的所有字段不能从主键索引上直接拿到,还需要从内存或磁盘上读取,所以不是覆盖索引。
另外,对于覆盖索引,要注意的是,where条件也会影响查询是否使用到覆盖索引。依然用idx_name_age索引,假设user表上有birthday,那么下列查询也不会使用覆盖索引。
SELECTname,ageFROMuserWHEREbirthday='2019-04-26';
题主可以考虑下,为什么上面这个查询没有使用到覆盖索引。
                            
查看完整回答
反对 回复 2019-04-27
  • 2 回答
  • 0 关注
  • 351 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信