为什么 MySQL 单表数据量最好别超过 2000w

一、序言

今天和大家讨论一下 MySQL 单表数据量多大合适。

二、B+ 树

B+ 树是一种数据结构,由分支节点和叶子节点组成。叶子节点存储数据,而分支节点仅用于索引和导航。B+ 树的叶子节点形成一个有序链表,可以通过叶子节点进行范围查询和顺序遍历。此处只对 B+ 树的概念做个引入,有关 B+ 树更详细的内容请大家借助搜索引擎哦 ^_^。

三、InnoDB 存储引擎

在 MySQL 中,默认的存储引擎是 InnoDB 存储引擎,InnoDB 存储引擎底层默认采用的是 B+ 树的数据结构。稍微不同的是:InnoDB 存储引擎的 B+ 树叶子节点采用的是双向链表而不是单向链表。

在 InnoDB 引擎中,我们的行数据是放在页中的。页(Page)是 InnoDB 存储引擎磁盘管理的最小单元,每个页的大小默认为 16 KB

四、MySQL 单表数据量分析

现在,我们知道 MySQL 默认采用的是 InnoDB 存储引擎来存储数据,而 InnoDB 存储引擎底层是使用的 B+ 树数据结构。为了性能,一般我们需要保证 B+ 树的高度不要超过 3。我们以最大 B+ 树高度(高度为 3)来分析,看看能存储多大的数据量。

场景假设:

  1. B+ 树高度为 3
  2. 一行数据的大小为 1KB
  3. 存储引擎使用 InnoDB

在 InnoDB 中,最小的存储单元是页(16 KB),那么可计算出一页可存储:16 / 1 = 16(行)数据。

在 B+ 树中,我们知道数据存储在叶子节点,分支节点只存储索引(即 ID)和指向下一节点的指针。即:

  1. 分支节点存储的是行数据的 ID 和指向下一节点的指针
  2. 叶子节点存储的是真正的数据

InnoDB 中一个指针占用 6 个字节,假设我们的主键使用的是 bigint(占用 8 个字节)。那么一页可以存储多少个索引,多少个指针呢?

设:可存储索引个数为 n,则:

n ∗ 8 + ( n + 1 ) ∗ 6 = 16 ∗ 1024 n * 8 + (n + 1) * 6 = 16 * 1024 n∗8+(n+1)∗6=16∗1024

可解出 n ≈ 1170

那么,可以知道一页可存储约 1170 个索引,1170 + 1 = 1171 个指针。

我们知道 B+ 树的高度是 3,那么前两层都是索引,最后的叶子节点放的是数据,可计算出:

1171 ∗ 1171 ∗ 16 = 21939856 1171 * 1171 * 16 = 21939856 1171∗1171∗16=21939856(行)

即,树的高度为 3 时大约可以存储 2200w 行数据。

综上,我们计算出了 2200w 行是在行数据大小为 1KB(实际可能比这大),索引层数达到 3 层时的极限值,所以通常情况下我们以 2000w 为一个分界点来表述单表容量的上限。但是这只是一个参考值,因为这 2000w 的计算参数可能与我们在生产实践中的参数出入很大。

往期推荐

  1. ConcurrentHashMap 源码分析(一)
  2. IoC 思想简单而深邃
  3. ThreadLocal
  4. Spring 三级缓存
  5. RBAC 权限设计(二)
相关推荐
李白客7 分钟前
KES新版MySQL兼容能力再升级意味着什么?
mysql·国产数据库
ClouGence2 小时前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
飞将5 小时前
从零实现数据库(2)——HashIndex + IndexManager
数据库
Nturmoils1 天前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
渣波1 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
Jim6002 天前
【吃透 MySQL InnoDB连载】第 1 章・解密线上数据库高频故障
mysql
GreatSQL2 天前
gt-checksum v4.0.0 新功能解读系列文章(4):SSL 加密连接——数据校验传输安全再升级
mysql
倔强的石头_2 天前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
倔强的石头_5 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库