本文主要是介绍快速理解 Mysql 回表 索引覆盖 索引下推,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
快速理解 Mysql 回表 索引覆盖 索引下推
- 回表操作
- 索引覆盖
- 索引下推
回表操作
Mysql 每页大小为16K(B+树结构,所以16K足以),关于主键索引和辅助索引的结构这里简单说一下。
InnoDB 主键(聚簇索引):仅在叶子节点存储数据,且是整行数据。
InnoDB 普通索引(辅助索引):仅在叶子节点存储对应的主键。
比如:
有一张
account表,其中id为主键,name为普通索引,age无索引。
| id | name | age |
|---|---|---|
| 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 = '张三';
我们仅需要查询id和name,我们通过name索引即可获取到主键,又因为name我们直接使用的是=查询(过滤出来的name绝对就是张三,不可能是其他的),所以无需再进行回表操作,这就叫索引覆盖。
那么考虑一下,下面这条语句会进行回表吗?
select id,name from account where name like '张%';
注意,我将=换成了like。
答案是会进行回表,因为有很多个张姓,like在右侧%虽然是会用到
name索引,但通过name索引我们仅能过滤出了所有张姓的人,此时通过叶子节点只能获取到对应主键,所以需要主键去回表得到具体的name。
索引下推
假设
account表数据表结构如下
id为主键索引,name和age为联合索引
| id | name | age |
|---|---|---|
| 1 | 张一 | 90 |
| 2 | 张二 | 91 |
| 3 | 张三 | 92 |
| 4 | 李四 | 93 |
select * from account where name like '张%' and age=90;
首先name和age是联合索引,且查询符合最左匹配原则,会使用索引进行查询。
mysql 5.6之前
忽略掉age字段,仅通过name字段索引找到符合条件的数据(3个),然后进行回表操作,再去判断age是否符合.,由于找到3条符合条件的数据,所以需要3次回表操作。
mysql 5.6之后
不忽略age字段,在索引内部直接判断age是否同样符合条件,所以仅能找到1条符合条件的数据,因为我们用的是like,所以还是需要回表,但仅需要回表1次。
这篇关于快速理解 Mysql 回表 索引覆盖 索引下推的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!