覆盖索引是指一个查询所需访问的所有列,都完整地存在于同一个索引中。当查询能利用覆盖索引时,MySQL 只需扫描该索引的 B+ 树叶子节点,就能直接拿到全部需要的字段值,完全无需回表访问聚簇索引(主键索引),从而大幅减少磁盘 I/O 次数,是 MySQL 中最常见、最有效的查询优化手段之一。
🌳 一、覆盖索引的核心原理
在 InnoDB 的二级索引(普通索引或唯一索引)里:
- 叶子节点存储:索引列的值 + 对应的主键值。
- 假设表有主键 id,索引 idx_name (name),其叶子记录为 (name, id)。
当执行 SELECT id, name FROM users WHERE name = \’Alice\’ 时:
- 查询仅需要 id 和 name。
- 而 idx_name 的叶子节点正好包含了 name 和 id。
- 引擎扫描 idx_name 找到 \’Alice\’ 对应的叶子记录后,直接获得所需数据,不需要再根据 id 去聚簇索引查整行。
这就是“覆盖”的含义:索引覆盖了查询所需的全部列,索引本身即可满足查询,无需回表。
📊 二、如何判断使用了覆盖索引?
使用 EXPLAIN 查看执行计划,如果 Extra 列出现 Using index,就表示此次查询使用了覆盖索引。
EXPLAIN SELECT id, name FROM users WHERE name = \’Alice\’;
