祗疼妳一个 发表于 2025-3-13 05:44:20

3-001:MySQL 中的回表是什么?

1. 什么是回表?

回表(Back to Table) 指的是 在使用非聚簇索引(辅助索引)查询时,MySQL 必要 先通过索引找到主键 ID,然后再回到主键索引(聚簇索引)查询完整数据,这一过程称为回表。
2. 回表的示例

假设有一张 users 表:
CREATE TABLE users (
    id INT PRIMARY KEY,       -- 主键
    name VARCHAR(50),         -- 用户名
    age INT,                  -- 年龄
    address VARCHAR(255),      -- 地址
    INDEX idx_name (name)      -- 创建 name 的辅助索引
) ENGINE=InnoDB;
如果实行以下查询:
SELECT address FROM users WHERE name = 'Alice';

查询实行过程:

[*]先查 idx_name 索引,找到 name='Alice' 对应的 id(假设 id = 3)。
[*]再回表查询,根据 id=3 在聚簇索引(主键索引)中找到 address 字段。
   为什么要回表? 由于 idx_name 只存了 name 和 id,但 address 不在索引中,必须再回到主键索引查找完整数据。
3. 什么情况下会发生回表?



[*]查询的字段不在索引覆盖范围内(即非覆盖索引查询)。
[*]使用二级索引(非主键索引)查询,而查询的字段不在索引列中。
4. 怎样避免回表?

(1)使用覆盖索引

如果查询的字段已经包含在索引中,就可以避免回表:
CREATE INDEX idx_name_age ON users(name, address);
然后实行:
SELECT address FROM users WHERE name = 'Alice';

此时,idx_name_age 索引已经包含 name 和 address,以是可以直接在索引中获取数据,不必要回表。
(2)使用主键查询

如果使用 id(主键)查询,就不必要回表:
SELECT address FROM users WHERE id = 3;
由于 InnoDB 的主键索引(聚簇索引)本身就存储了完整数据,以是查询 id 不会回表。
5. 总结

查询方式是否回表缘故原由主键查询 (SELECT * FROM users WHERE id = 3)❌ 不会由于主键索引(聚簇索引)包含完整数据非主键索引查询 (SELECT address FROM users WHERE name = ‘Alice’)✅ 会回表先查 name 索引,再回表查 address覆盖索引查询 (SELECT name FROM users WHERE name = ‘Alice’)❌ 不会name 索引已经包含查询字段   
页: [1]
查看完整版本: 3-001:MySQL 中的回表是什么?