为什么 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 权限设计(二)
相关推荐
技术宝哥几秒前
Redis(2):Redis + Lua为什么可以实现原子性
数据库·redis·lua
学地理的小胖砸1 小时前
【Python 操作 MySQL 数据库】
数据库·python·mysql
dddaidai1232 小时前
Redis解析
数据库·redis·缓存
数据库幼崽2 小时前
MySQL 8.0 OCP 1Z0-908 121-130题
数据库·mysql·ocp
Amctwd2 小时前
【SQL】如何在 SQL 中统计结构化字符串的特征频率
数据库·sql
betazhou3 小时前
基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
linux·数据库·mysql·oracle·ogg
lyrhhhhhhhh3 小时前
Spring 框架 JDBC 模板技术详解
java·数据库·spring
喝醉的小喵4 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
付出不多5 小时前
Linux——mysql主从复制与读写分离
数据库·mysql
初次见面我叫泰隆5 小时前
MySQL——1、数据库基础
数据库·adb