跳到主要内容
约 4 分钟4 张卡

聚簇索引

InnoDB 使用聚簇索引组织行数据。本文讲解 MySQL 8.0 的聚簇键选择和维护成本。

1. 面试核心​

先记住这几条,再读正文

2. 聚簇索引​

InnoDB 按聚簇键顺序组织叶子记录。叶子记录组织该行的所有列。DYNAMIC 行格式可将较长的变长值放入溢出页。叶子记录保存指向这些值的指针。

SELECT * FROM users WHERE id = 42;

若 id 是主键,查到聚簇叶子便能定位整行。存在页外值时,还需读取溢出页。

一张 InnoDB 表只有一个聚簇索引。键顺序是逻辑顺序,相邻页在磁盘上可以分散存放。

3. 没有主键时的聚簇索引​

InnoDB 按以下顺序选择聚簇键:

  1. 表有显式主键时,使用主键。
  2. 否则使用第一个所有列都非空的唯一索引。
  3. 两者都缺少时,生成 6 字节隐藏行 ID。

隐藏聚簇索引名为 GEN_CLUST_INDEX。它的行 ID 由 InnoDB 内部维护。应用需要稳定引用一行时,应定义显式主键。

4. 二级索引与回表​

二级索引包含聚簇键,查询缺失列时需要回表。访问步骤见联合索引与覆盖索引。

5. 覆盖索引​

覆盖查询满足取列需求,版本判断仍可访问聚簇记录。机制见联合索引与覆盖索引。

6. 主键宽度​

二级索引记录包含聚簇键。主键越宽,每个二级索引的定位信息就越大。同一页能容纳的记录更少,缓存也需承担更多空间。

短而稳定的键能减少这些成本。递增键把写入集中到右侧,随机键分散写入位置。页面调整的过程见 插入、删除与页分裂。

7. 主键更新​

主键更新会改变行的聚簇键。InnoDB 要调整聚簇记录,并维护二级索引的定位信息。二级索引越多,维护范围越大。

业务编号经常变化时,可用稳定 ID 作为主键。业务编号另设唯一约束。编号修改便无需同时改变所有二级索引的定位键。

8. 范围查询与排序​

主键范围查询可以沿聚簇叶子顺序读取。

SELECT * FROM users
WHERE id >= 10000 AND id < 10100;

二级索引范围查询需要完整行时,还需按聚簇键取列。返回行数很多时,回表成本随之增加。优化器据此比较二级索引访问和聚簇索引扫描。

9. 常见问题​

9.1 主键与存储引擎​

在 InnoDB 中,显式主键就是聚簇索引。其他存储引擎有各自的行组织方式。回答时应先说明数据库和存储引擎。

9.2 二级索引的覆盖查询​

10 · 面试题卡片​

本页题目与参考回答

10.1 InnoDB 聚簇索引和二级索引有什么区别,什么情况下会回表​

考察重点

  • 聚簇索引的行组织方式。
  • 二级索引叶子中的主键与回表路径。
  • 覆盖查询、主键宽度和范围读取。

相关内容:聚簇索引至范围查询与排序。

参考回答

聚簇索引组织整行,二级索引组织索引列和聚簇键。

InnoDB 有显式主键时,用它作为聚簇键。二级索引缺少查询所需列时,需按聚簇键回表。

覆盖查询可省去取列回表,版本检查仍可访问聚簇记录。较宽的主键会增加二级索引占用。频繁修改主键也会扩大维护范围。

10.2 覆盖索引为什么仍可能访问聚簇索引?​

考察重点

  • 查询列覆盖与可见性
  • 二级索引版本检查

相关内容:覆盖索引。

参考回答

覆盖索引只满足取列需求,MVCC 还需要判断版本可见性。

二级索引记录缺少完整版本信息。遇到删除标记或较新的页修改时,会检查聚簇记录。必要时再通过 undo 构造可见版本。

10.3 没有主键时 InnoDB 如何组织行,选择主键要考虑什么?​

考察重点

  • 聚簇键选择顺序
  • 宽度、稳定性、写入分布

相关内容:没有主键时的聚簇索引、主键宽度。

参考回答

InnoDB 先选第一个全列非空的唯一索引。

没有合适索引时,使用隐藏的 6 字节行 ID。主键设计还要考虑宽度、稳定性和插入分布。显式主键便于应用、同步工具和迁移任务定位行。

10.4 为什么频繁修改主键会增加二级索引维护成本?​

考察重点:聚簇键定位与稳定主键设计。

相关内容:主键更新。

参考回答

二级索引用聚簇键定位行,主键更新后定位键也要更新。

聚簇索引本身同样需要调整记录。业务编号易变时,可使用稳定 ID 聚簇。业务编号通过独立唯一约束保持唯一。

11. 参考资料​