为什么 MySQL 一张表几千万行按主键查一条数据只要几毫秒答案就在 MySQL 的索引结构里——B 树。B 树长什么样这是一张 B 树的示意图它是一个扇出为 3 的简化版本。与二叉树不同B 树可以有非常多的分支。树里包含三种节点根节点、非叶子节点和叶子节点。**只有叶子节点存储数据**根节点和非叶子节点都是索引层查询时从根节点开始一步步向下索引到叶子节点。叶子节点之间用指针串成链表——这让范围查询非常高效找到起点后顺着链表一路扫过去就行。严格说上面说的是聚簇索引二级索引的叶子节点存的是主键值这个留到下一篇写。图里是扇出 3 的简化示意真实 InnoDB 的扇出约 1170看下一段。为什么三层能存千万数据因为一个节点不是一条数据而是一个 16KB 的磁盘页。一个索引项 主键 8 字节 指针 6 字节 ≈ 14 字节一页能放下 16KB ÷ 14B ≈ 1170 个索引项。三层结构就是- 根页 1170 个指针 → 1170 个中间页- 每个中间页再分 1170 个指针 → 1170 × 1170 ≈ 137 万个叶子页- 假设一行数据约 1KB一个叶子页能存 16 行137 万 × 16 ≈ **2190 万行**所以三层 B 树能撑起千万级数据。行更大就长到四层量级一样。为什么比 B 树适合磁盘磁盘 IO 次数 树高一次 IO 读一页。B 树非叶子节点只存键和指针、不存数据同样 16KB 一页能装更多索引项——同样数据量下树更矮、IO 更少。而且数据全在叶子、叶子用链表串起来范围查询顺着链表一路扫就行B 树的数据散布在所有节点里范围扫描要反复上下树IO 多得多。所以不是 B 树不能范围查而是查起来慢——B 树在磁盘场景全面占优。总结回到开头的问题按主键查一条数据最多三次磁盘 IO根页 → 中间页 → 叶子页三次 IO 就是毫秒级。实际中根页常驻内存通常只要 1-2 次 IO。面试口径一句话**B 树高度低、叶子链表串联支持范围查询三层能存千万行**。