什么是回表(十二)
通俗来说
通俗的讲就是,如果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
在所有的矛盾中,要优先解决主要矛盾,其他矛盾也就迎刃而解。
不要做个笨蛋,为失去的郁郁寡欢,聪明的人,已经找到了解决问题的办法,或正在寻找。