外观
MySQL 一张表能创建几个 B + 树?
⭐ 题目日期:
字节 - 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)
可替代a
和b
的单列索引)。 - 定期清理:删除未使用的冗余索引。
5. 总结
索引类型 | B+ 树数量 | 说明 |
---|---|---|
聚簇索引 | 1 | 必选,存储行数据 |
二级索引 | 最多 64 | 每个索引对应一棵 B+ 树 |
全文/空间索引 | 0 | 不计入 B+ 树数量,使用其他数据结构 |
总 B+ 树数量 = 1(聚簇索引) + 二级索引数量(≤64)。
实际开发中应严格控制索引数量,避免过度设计!