先理解什么是回表查询
定义:
回表查询(Table Lookup或Back to Table)是数据库查询中的一个过程,指在使用非聚集索引(Secondary Index或Non-Clustered Index)定位数据时,由于索引节点中不包含查询所需的全部列,数据库需要根据索引找到数据行的位置(通常是主键或行标识符),然后回到聚集索引或数据表中读取完整的数据行。
这种行为通常发生在查询的字段未被索引覆盖,索引不足以直接满足查询需求时,如果索引列无法完全满足查询字段,则数据库会通过索引找到记录位置后回表读取非索引列的数据。
当你需要查询的ID1列,没有在索引命中时,优化器会根据你根据索引查到的ID列的数据,再回到主表中,匹配完整的ID1的数据,这就是回表,如果ID的数据很多,就会造成回表的次数很多,消耗大量的磁盘IO,导致查询变慢

如何避免回表
如果你查的所有字段都能在某个辅助索引的叶子节点中被包含,那么就不需要回表
举个例子:
表 user(id, name, age, email)
create table "user"
(
id int,
name varchar(10),
age int,
email varchar(100)
);
我们建立了一个索引:KEY idx_name_age(name, age)
然后执行 SQL:
SELECT age from "user" where name='李小明';

这时候:
- 这个SQL命中了 idx_name_age 索引。
- WHERE 和 SELECT 用到的字段(name和age)都在这个索引里。
- 所以不需要去主键索引那里回表,直接从二级索引就能拿到数据。
这就是经典的覆盖索引命中。
但是如果你执行的是:
SELECT email from "user" where name='李小明';

抱歉,虽然WHERE条件命中了idx_name_age,但你要拿email,它不在这个索引的叶子节点中,只好通过name索引查到主键,然后回主键索引的B+树去拿整行数据。
总结什么样的索引需要回表,什么样的索引,不需要回表
