面试题:如何计算InnoDB中B+树索引的层高

假设有一张user表中有200万条数据,表结构如下:

create table user(
  `id` bigint(64) NOT NULL COMMENT 'id主键',
  `user_name` varchar(64) DEFAULT NULL COMMENT '用户名'
  ...... //省略其他字段
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

首先,bigint 长度为 8 字节指针大小在 InnoDB 源码中设置为 6 字节,这样一共 14 字节。非叶子节点一页可以存储 16K/14byte=16*1024/14=1170 个这样的单元(键值+指针),代表有 1170 个指针。
然后,假设实际每一条记录的大小是 1K,那么每一个叶子节点可以存储 16K/1K=16条记录。
那么两层(一层非叶子节点,一层叶子节点)的B+树可以保存1170*16=18720条数据。三层(两层非叶子节点,一层叶子节点)的B+树可以保存1170 * 1170*16=21902400条数据。 因此200万条数据的表其实就是3层高。

在 InnoDB 中 B+ 树深度一般为 1-3 层。3层就已经能满足千万级的数据存储。


THE END.

### InnoDB 中 B+ 联合索引的工作原理 #### 1. 联合索引的概念 联合索引是指在一个表的个字段上建立的一个复合索引。它通过组合个列来提查询效率,尤其适用于涉及条件过滤的场景。在 MySQL 的 InnoDB 存储引擎中,联合索引基于 B+ 实现[^1]。 #### 2. 联合索引的结构特点 联合索引遵循最左前缀原则(Leftmost Prefix Rule)。这意味着当使用联合索引时,查询语句中的条件必须从索引定义的第一个字段开始匹配才能有效利用该索引。如果跳过某个中间字段,则后续字段无法被优化器用于索引扫描操作[^1]。 例如,在 `(col1, col2, col3)` 上建立了联合索引: - 查询 `WHERE col1 = ?` 可以命中此联合索引; - 查询 `WHERE col1 = ? AND col2 = ?` 同样可以命中; - 查询 `WHERE col1 = ? AND col3 = ?` 则可能部分命中,但不会完全覆盖整个索引路径; - 如果仅提供 `WHERE col2 = ? OR WHERE col3 = ?` 条件,则无法充分利用这个联合索引。 #### 3. 数据分布与检索过程 对于每一条记录来说,B+ 节点存储的是键值以及指向实际数据行的位置指针。假设存在一张名为 `users` 表,并在其三个属性 (`age`, `gender`, `city`) 创建了一个联合索引: ```sql CREATE INDEX idx_age_gender_city ON users(age, gender, city); ``` 此时,B+ 会按照先按年龄排序再依次细分性别最后到城市的方式构建层次化形结构。这样做的好处是可以加速那些同时指定这三个维度筛选标准的操作速度;而缺点在于单就某一方面进行查找可能会失去原本预期的效果因为缺少单独针对这些子集设计好的次级分支链接关系[^1]。 #### 4. 实际应用案例分析 考虑下面这段 SQL 请求: ```sql SELECT * FROM users WHERE age >= 18 AND age <= 60 AND gender='male' ORDER BY city; ``` 由于已经预先设置了包含所有必要参数在内的综合型索引即上面提到过的那个三重组合形式(`idx_age_gender_city`) ,所以这里可以直接借助现有的这棵经过精心调整后的平衡二叉搜索来进行效定位目标群体成员位置并返回结果列表无需额外执行文件排序动作从而节省大量计算资源消耗时间成本等方面的优势变得非常明显起来[^2]。 --- ### 总结 综上所述,InnoDB 中 B+ 联合索引的设计理念主要是为了满足复杂业务逻辑下频繁出现的各种混合类型约束条件下快速获取所需信息的需求。然而值得注意的一点就是开发者们应当充分理解自己所处具体应用场景的特点进而合理规划数据库对象之间的关联模式以便达到最佳性能表现水平的同时也要兼顾维护便利性和扩展灵活性等个方面因素共同考量最终做出明智决策[^1][^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值