InnoDB 采用 B+ 树存储,真正的数据行存在聚簇索引的叶子节点上
B+ 树的每个节点是一页,一页固定大小是 16k ,其中 1k 是页头,15k 是可以存放 索引/数据行 的空间
B+ 树的层数要尽可能小,以减少查找数据时磁盘 IO 的次数(磁盘 IO 很慢),实际中一般是 3 层
下面假设 B+ 树一共是三层,第一、二层用来存主键索引,第三层用来存数据行(聚簇索引)
用来存储索引的一页(非叶子节点):
由于是聚簇索引,一般都是主键作为索引列,假设主键为 bigInt 类型(8byte),每个索引列还需要页号(4byte),用来指向下一层的B+树节点(页),所以一个索引列大小是 12byte
那么一页可以存储 15*1024/12 = 1024 行索引列
B+ 树必有一个根节点,根节点可以存 1024 行索引列,那么也就会指向第二层的 1024 个 B+ 树节点(一个节点是一页)
第二层每个页也用来存索引,每个页可存 1024 行索引,那么每页就会指向 1024 个第三层的叶子节点(1024页),所以第三层叶子节点页的数量为 1024*1024
用来存储数据行的一页(叶子节点):
假设一行数据是 1k ,那么一页的可用空间 15k 可以存储 15 个数据行
如果一行数据大于或小于 1k ,那么一页可以存储的数据行还会小于或大于 15
综上,第三层叶子节点的数量总共为 1024*1024,每个叶子节点可以存 15 行数据,第三层可以存 1024*1024*15 = 24576000 (约 2.45kw)个数据行
所以,三层可以存的数据量大约就是 2000w,如果要存储更多的数据,那么意味着:
- 要增加 B+ 树高度,每次查询磁盘 IO 的次数就会增加,速度就会变慢
- MySQL 为了提高性能,会将表的索引装载到内存中,在 InnoDB buffer size 足够的情况下,其能完成全加载进内存,查询不会有问题。但是,当单表数据库到达某个量级的上限时,导致内存无法存储其索引,使得之后的 SQL 查询会产生磁盘 IO,从而导致性能下降。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· DeepSeek “源神”启动!「GitHub 热点速览」
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器