快速理解 Mysql 回表 索引覆盖 索引下推

快速理解 Mysql 回表 索引覆盖 索引下推

回表操作

Mysql 每页大小为16K(B+树结构,所以16K足以),关于主键索引和辅助索引的结构这里简单说一下。
InnoDB 主键(聚簇索引):仅在叶子节点存储数据,且是整行数据
InnoDB 普通索引(辅助索引):仅在叶子节点存储对应的主键

比如:

有一张account表,其中id为主键,name为普通索引,age无索引。

idnameage
1张一90
2张二91
3张三92
4李四93

此时如果执行

select * from account where name = '张三';
# 下面这条语句和上面相同
select id,name,age from account where name = '张三';

虽然name建立了索引,但是普通索引叶子节点仅存储该列对应的主键,我们select *包含了无索引的age字段,所以需要①通过name索引找到主键,②去主键索引的b+树中找整行记录

这个通过普通索引找对应主键,再去主键索引中寻找数据的过程,我们叫作回表

索引覆盖

如果是这条语句就不会进行回表操作:

select id,name from account where name = '张三';

我们仅需要查询idname,我们通过name索引即可获取到主键,又因为name我们直接使用的是=查询(过滤出来的name绝对就是张三,不可能是其他的),所以无需再进行回表操作,这就叫索引覆盖


那么考虑一下,下面这条语句会进行回表吗?

select id,name from account where name like '张%';

注意,我将=换成了like

答案是会进行回表,因为有很多个张姓,like在右侧%虽然是会用到name索引,但通过name索引我们仅能过滤出了所有张姓的人,此时通过叶子节点只能获取到对应主键,所以需要主键去回表得到具体的name

索引下推

假设account表数据表结构如下
id为主键索引,name和age为联合索引

idnameage
1张一90
2张二91
3张三92
4李四93
select * from account where name like '张%' and age=90;

首先nameage是联合索引,且查询符合最左匹配原则,会使用索引进行查询。

mysql 5.6之前
忽略掉age字段,仅通过name字段索引找到符合条件的数据(3个),然后进行回表操作,再去判断age是否符合.,由于找到3条符合条件的数据,所以需要3次回表操作。

mysql 5.6之后
不忽略age字段,在索引内部直接判断age是否同样符合条件,所以仅能找到1条符合条件的数据,因为我们用的是like,所以还是需要回表,但仅需要回表1次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没事干写博客玩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值