Skip to content

MySQL 一张表能创建几个 B + 树?

约 783 字大约 3 分钟

MySQL字节

2025-03-20

⭐ 题目日期:

字节 - 2024/12/25

📝 题解:


在 MySQL 中,每张表的索引数量直接决定了其对应的 B+ 树数量。具体规则如下:


1. B+ 树的数量规则

  • 每个索引对应一棵 B+ 树:无论是主键索引还是二级索引,每个索引都是一个独立的 B+ 树结构。
  • 默认必有 1 棵 B+ 树:即使未显式定义主键,InnoDB 也会生成隐式的聚簇索引(基于 ROW_ID)。
  • 二级索引数量限制
    • 默认限制:单张表最多支持 64 个二级索引(MySQL 5.7+,早期版本可能不同)。
    • 总 B+ 树数量1(聚簇索引) + 64(二级索引) = 65 棵

2. 索引类型与 B+ 树的关系

(1) 聚簇索引(Clustered Index)

  • 必须存在:每个表有且仅有一个聚簇索引。
  • 存储数据:叶子节点直接存储行数据,与主键绑定。
  • 隐式主键:若未显式定义主键,InnoDB 会自动生成隐藏的 ROW_ID 作为聚簇索引。

(2) 二级索引(Secondary Index)

  • 额外 B+ 树:每个二级索引(如普通索引、唯一索引、联合索引)对应一棵独立的 B+ 树。
  • 存储主键值:叶子节点存储主键值,查询时需回表(通过聚簇索引获取完整数据)。

(3) 特殊索引

  • 全文索引(FULLTEXT):基于倒排索引(非 B+ 树)。
  • 空间索引(SPATIAL):基于 R 树(非 B+ 树)。
    • 注意:这两类索引不计入 B+ 树数量限制。

3. 验证索引数量限制

(1) 通过 CREATE INDEX 测试

-- 创建测试表
CREATE TABLE test (
  id INT PRIMARY KEY AUTO_INCREMENT,
  col1 INT,
  col2 INT,
  ...
  col64 INT
);

-- 尝试为每个字段创建索引(共 64 个二级索引)
CREATE INDEX idx_col1 ON test(col1);
CREATE INDEX idx_col2 ON test(col2);
...
CREATE INDEX idx_col64 ON test(col64);

-- 第 65 个索引会报错:
-- ERROR 1069 (42000): Too many keys specified; max 64 keys allowed

(2) 查看索引信息

SHOW INDEX FROM test;
-- 结果中将显示聚簇索引(PRIMARY)和所有二级索引。

4. 为什么限制为 64 个二级索引?

  • 性能与存储权衡

    • 写入代价:每个索引的增删改需维护对应的 B+ 树,索引过多会显著降低写性能。
    • 存储开销:每个索引占用额外磁盘空间。
    • 优化器选择:索引过多可能导致优化器选择低效的执行计划。
  • 实际建议

    • 按需创建:仅为高频查询条件或排序字段创建索引。
    • 联合索引优先:通过联合索引减少索引数量(如 (a, b) 可替代 ab 的单列索引)。
    • 定期清理:删除未使用的冗余索引。

5. 总结

索引类型B+ 树数量说明
聚簇索引1必选,存储行数据
二级索引最多 64每个索引对应一棵 B+ 树
全文/空间索引0不计入 B+ 树数量,使用其他数据结构

总 B+ 树数量 = 1(聚簇索引) + 二级索引数量(≤64)
实际开发中应严格控制索引数量,避免过度设计!