每日一Go·MySQL-9、索引存储结构|页分裂、页合并、索引高度与磁盘

一、MySQL 为什么以"页"为最小存储单位?

InnoDB 最小存储单位不是行,而是 Page(页)

apache 复制代码
1 Page = 16KB
  1. 为什么是 16KB?
维度 说明
磁盘 IO 16KB 顺序读性价比最高
空间利用 兼顾碎片率和读写效率
内存管理 Buffer Pool 换页高效

页是 MySQL 磁盘 IO 的最小单位,也是性能调优的根基

二、索引在磁盘上的真实结构

B+Tree 并不是逻辑结构,而是物理存储结构

apache 复制代码
B+Tree 的每一个节点 = 一个 16KB 数据页
  1. 三层 B+Tree 真实形态:
css 复制代码
Root Page
   ↓
Internal Page
   ↓
Leaf Page(索引页 / 数据页)

特点:

真正影响性能的是:叶子节点访问效率

三、页内部结构拆解

css 复制代码
Page(16KB)
 ├── File Header
 ├── Page Header
 ├── Infimum + Supremum
 ├── User Records   ← 行数据 / 索引数据
 ├── Free Space
 └── Page Trailer

关键:

sql 复制代码
User Records + Free Space = 可写入空间

四、页分裂(Page Split)------性能杀手

页分裂是 MySQL 写性能下降的最大元凶

  1. 什么是页分裂?

当页被写满后插入新数据:

复制代码
插入新行
   ↓
页已满
   ↓
申请新页
   ↓
拆分一半数据
   ↓
页分裂发生
  1. 页分裂示意
makefile 复制代码
原页: [1 2 3 4 5 6 7 8]
插入: 5.5

→ 分裂 →

页1: [1 2 3 4]
页2: [5 5.5 6 7 8]
  1. 页分裂带来的 4 大问题
影响 后果
申请新页 磁盘 IO 增多
数据移动 大量随机 IO
页不连续 顺序读变随机读
树高增加 查询 IO 次数变多

页分裂 = IO 风暴 + 性能雪崩

五、页合并(Page Merge)

删除 ≠ 回收空间

  1. 什么时候发生页合并?

    页利用率 < 50%
    ↓
    触发合并

  2. 页合并示意

makefile 复制代码
页A: [1 2]
页B: [3 4]

→ 合并 →

页A: [1 2 3 4]
  1. 页合并代价

频繁 delete 会导致系统性能不稳定

六、主键为什么必须单调递增?

这是 数据库索引设计的灵魂法则

  1. 自增主键插入流程

    永远写入最右叶子节点
    ↓
    顺序写磁盘
    ↓
    几乎无页分裂

  2. UUID 主键插入流程

    随机定位页
    ↓
    频繁页分裂
    ↓
    随机 IO 激增

  3. 性能对比

主键类型 写入性能
自增ID 5星
UUID 1星

主键选错,性能直接腰斩

七、索引高度 & 磁盘 IO 次数

树高 = 一次查询的磁盘 IO 次数

  1. 树高与 IO 对应关系

    树高 1 → 1 次 IO
    树高 2 → 2 次 IO
    树高 3 → 3 次 IO

  2. 数据规模 & 树高关系

数据量 树高
100万 2 ~ 3
1000万 3
1亿 3 ~ 4

亿级数据,一次查询通常 ≤ 4 次磁盘 IO

八、为什么索引字段要"短"?

假设:

复制代码
索引项 20B → 1 页 ≈ 800 条
索引项 40B → 1 页 ≈ 400 条

结果:

复制代码
索引变长 → 扇出减半 → 树高增加 → IO 增加

字段越短,性能越好

九、索引存储设计 5 大黄金法

markdown 复制代码
1. 主键必须递增
2. 索引字段尽量短
3. 避免 UUID 主键
4. 控制索引数量
5. 用联合索引代替多个单列索引

十、面试官最爱 5 连问

十一、底层认知模型

复制代码
页结构 → 页分裂 → IO 次数 → 树高度 → 查询性能

这条链路,决定了 MySQL 性能上限

源码地址

1、https://pan.baidu.com/s/1B6pgLWfSgMngVeFfSTcPdg?pwd=jc1s


如果您喜欢这篇文章,请您(点赞、分享、亮爱心),万分感谢!

相关推荐
星恒随风4 小时前
MySQL 从零入门(五):MySQL 内置函数详解——日期、字符串、数学函数与实战案例
linux·数据库·笔记·sql·mysql
吴名氏.6 小时前
Java转AI Agent教程(第十三周)混合检索与重排
java·数据库·人工智能·ai·ai agent
爱码少年6 小时前
Springboot下如何将CSV文件数据导入H2、Mysql数据库表
数据库·mysql·csv
2603_969694857 小时前
【JavaWeb学习记录】MyBatis核心知识点与实战笔记:从入门到动态SQL
笔记·sql·学习·mysql·mybatis·javaweb·学习方法
可乐ea7 小时前
智能体记忆该拆成几层:笔记、记忆表示与注入上下文
服务器·数据库·笔记·ai智能体·提示词工程·上下文工程·记忆系统
阿义有问题8 小时前
MySQL 迁移达梦全流程实战:DTS 七步图解 + 对象名全大写适配(附踩坑清单)
数据库
猫猫不是喵喵.11 小时前
从0到1创建一个微服务项目
java·数据库·微服务·1024程序员节
lsc_blog12 小时前
听到优化风声,先准备能由自己掌控的事
数据库·分布式·中间件·职场和发展·重构
墨痕诉清风12 小时前
SSRF漏洞实战记录+OSS桶命令执行+MCP漏洞
linux·服务器·数据库
Ashe81315 小时前
MySQL 慢日志先别急着加索引:三个指标能拦掉大半误判
数据库