核心内容摘要
程序人生:以终身学习保障职业生涯持续发展
“MySQL 的每个 B 树叶子节点是一行数据”—— 这个说法不完全准确。
在InnoDB 存储引擎中B 树的叶子节点存储的是完整的行数据聚簇索引或主键值二级索引但一个叶子节点通常包含多行数据而非“一行一节点”。
B 树节点结构页Page是基本单位▶
InnoDB 页Page大小默认16KB可配置类型数据页Leaf Page存储实际数据索引页Non-Leaf Page存储指针▶
叶子节点内容索引类型叶子节点存储内容聚簇索引主键索引完整行数据包括所有列二级索引辅助索引索引列 主键值核心认知一个叶子节点 一个 16KB 页 ≈ 多行数据非单行
聚簇索引 vs 二级索引▶
聚簇索引Clustered Index结构[页1: 行1, 行2, ..., 行N] ↔ [页2: 行N1, ..., 行M] ↔ ...特点数据即索引行数据按主键顺序存储在叶子节点无需回表直接返回完整数据▶
二级索引Secondary Index结构[页1: (nameAlice, id
, (nameBob, id
, ...]特点索引列 主键叶子节点不存完整数据需要回表通过主键到聚簇索引查完整行关键点二级索引的叶子节点 ≠ 完整行数据
行数据如何填充分页▶
行格式Row FormatCompact默认每行包含变长字段长度列表 NULL 标记 数据Dynamic推荐大字段如 TEXT/BLOB仅存指针数据存溢出页▶
单页容纳行数计算公式每页行数 ≈ 16KB / 单行平均大小示例行大小 1KB → 每页 ≈ 15 行行大小 100B → 每页 ≈ 150 行▶
分裂与合并插入新行若页满 →分裂为两个页5:5 或 9:1删除行若页利用率 50% →尝试合并相邻页
查询如何利用 B 树▶
等值查询主键SELECT*FROMusersWHEREid100;路径根节点 → 非叶子节点 →定位到包含 id100 的页在页内二分查找具体行▶
范围查询主键SELECT*FROMusersWHEREidBETWEEN100AND200;路径定位起始页 →顺序遍历双向链表直到结束▶
二级索引查询SELECT*FROMusersWHEREnameAlice;路径在name 索引找到(nameAlice, id
用id100回表到聚簇索引查完整行
避坑指南陷阱破局方案认为“一行一节点”理解页是存储单位单页含多行忽略回表成本高频查询用覆盖索引避免回表盲目增大页大小16KB 是平衡 I/O 与内存的最优值
终极心法**“B 树不是链条而是分块的仓库——当你理解页结构你在校准存储当你区分索引类型你在优化查询当你计算行密度你在铸造性能。
真正的数据库能力始于对页的敬畏成于对细节的精控。
”结语从今天起用SHOW TABLE STATUS查看行平均大小高频查询设计覆盖索引避免回表理解页分裂对写性能的影响因为最好的索引设计不是盲目建索引而是精准控制每一比特的存储。