mysql联合索引只建一棵b+树,按字段定义顺序逐级排序:先按city升序,相同city再按name升序,city和name都相同时再按age升序;非叶子节点仅存前缀值用于路由,叶子节点才存完整字段组合;跳过前导列(如仅查name)无法走索引,因无单独排序结构。

排序规则:从左到右,多级嵌套
比如建了 INDEX idx_city_name_age (city, name, age),B+ 树的排序逻辑是:
- 第一级:所有数据先按 city 升序排列(如 北京 → 广州 → 杭州 → 上海);
- 第二级:相同 city 的记录,再按 name 升序排列(如“杭州”下的 张三 → 王五 → 钱七);
- 第三级:city 和 name 都相同的记录,最后按 age 升序排列。
这就像查纸质电话簿:必须先翻到“姓氏”页(city),再在该姓氏下找“名字”(name),名字还重复时才看“中间名或年龄”(age)。
叶子节点实际存储顺序严格遵循该规则
以 (city, name) 索引为例,叶子节点中数据的真实物理顺序是:
| city | name | 主键 id |
|---|---|---|
| 杭州 | 张三 | 1 |
| 杭州 | 王五 | 3 |
| 杭州 | 钱七 | 5 |
| 北京 | 李四 | 2 |
| 上海 | 赵六 | 4 |
| 广州 | 周九 | 7 |
注意:没有“北京→张三”或“王五→杭州”这类跨顺序的组合——因为 B+ 树不支持跳过前导列重新排序。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
非叶子节点只存前缀,用于快速定位
非叶子节点(中间层)不存完整字段,只存用于导航的“最小前缀值”:
- 根节点或内节点可能只存 city 值(如:北京、杭州、上海、广州);
- 它们的作用是快速把查询路由到对应 city 的子树;
- 只有落到叶子节点后,才会看到 city + name + 主键 的完整组合,并且 name 在同一 city 下是有序的。
为什么不能跳过左边字段?
因为 B+ 树没有为 name 单独建排序结构。如果执行 WHERE name = '张三',引擎无法知道“张三”分布在哪些 city 下、是否连续、从哪一页开始找——就像没写姓氏就让图书管理员找“小明”,他根本没法从书架头开始高效扫描。
同理,WHERE city = '杭州' AND age > 25 可以利用前两列(city 定位 + name 全局无序但 age 在 name 下有序),但 age 列之后的排序失效,无法用于范围或排序加速。










