什么是回表(十二)

通俗来说

通俗的讲就是,如果select所需获得列中有非索引列,一次索引查询不能获取所有信息,需要到表中找到相应的列的信息。这就叫回表。也就是说,需要从辅助索引(Secondary Index)中获取额外的数据列,需要通过辅助索引回到主键索引(Primary Index)中进行查找。

而如果根据一次索引查询就能获得所有列信息,就不需要回表。

具体定义

当执行一个查询语句,包含了辅助索引的列时,MySQL会首先使用辅助索引定位到符合条件的记录的主键值,然后再根据这些主键值去主键索引查找对应的完整数据行。这个过程就被称为回表。

举例说明

举个例子,先创建一张表:

create table one_place(
    id int(10) not null,
    name varchar(16),
    gender varchar(8),
    index(name),
    primary key(`id`) using btree
)engine = InnoDB;

插入几条测试数据:

不需要回表的情况

覆盖索引查询:如果查询语句中的字段都包含在辅助索引中,且辅助索引覆盖了查询所需的所有字段,就不会触发回表操作。此时,MySQL可以直接从辅助索引中获取查询所需的数据,而无需回到主键索引。
使用聚集索引进行查询:如果查询语句使用聚集索引(即主键索引)进行查询,并且所需的字段都包含在聚集索引中,就不会触发回表操作。因为聚集索引中包含了完整的数据行,可以直接从聚集索引中获取所需的数据。

具体实例

假设,现在我们要查询出id为2的数据,执行查询语句:

select * from one_piece where ID = 2;

这条SQL语句就不需要回表。原因是根据主键的查询方式,只需要搜索id这颗B+树。

主键是唯一的,根据这个唯一的索引,MySQL就能确定搜索的记录。

id为主键索引,主键索引是聚簇索引。

聚簇索引的叶子节点包含整个行记录,一次索引查询就能获取所有的信息。故不需要回表。

需要回表的情况

SELECT语句使用了非聚集索引:如果查询语句使用了非聚集索引(辅助索引)并需要返回非索引字段的值,就会触发回表操作。因为辅助索引中只包含索引列的值,而非索引字段的值存储在主键索引中,所以需要回到主键索引中获取完整的数据行。
查询包含了不在索引中的字段:如果查询语句需要返回不在辅助索引中的字段,就会触发回表操作。因为辅助索引中只包含索引列的值,如果查询需要返回其他字段的值,就需要回到主键索引中获取完整的数据行。

具体实例

比如查询name为索隆的记录,使用查询语句select * from one_piece where name = “索隆”

这个查询语句就需要回表,原因是通过name这个普通索引查询方式,需要先搜索name索引树,然后得到主键id的值为2,再到id索引树搜索一次。

即先定位主键值,再定位行记录。

这个过程虽然用了索引,但实际上底层进行了两次索引查询,这个过程就称为回表。也就是,基于非主键索引的查询需要多扫描一颗索引树。

我们在应用中应该尽量使用主键查询。当表数据量很大的时候,可以很明显的看出两次查询所用的时间的差距,使用主键查询效率更高。

回表造成的性能影响

回表操作可能会影响查询性能,因为需要在辅助索引和主键索引之间进行额外的IO操作。特别是当查询的结果集包含辅助索引无法直接覆盖的列时,回表的开销更加明显。

如何避免回表

为了避免过多的回表操作,可以考虑使用覆盖索引(Covering Index)来优化查询。覆盖索引是指辅助索引包含了查询所需的所有列,这样查询就可以直接从辅助索引中获取所需的数据,而不需要回表操作。
原文链接:https://blog.csdn.net/qq_46130027/article/details/131020002

posted @ 2020-10-09 10:18  慎终若始  阅读(248)  评论(0编辑  收藏  举报