为什么 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 权限设计(二)
相关推荐
重生之我是Java开发战士6 分钟前
【MySQL】数据库基础
数据库·mysql
ChuHsiang11 分钟前
【剑指MySQL】数据库基础(1)
数据库·mysql
九皇叔叔20 分钟前
Docker 镜像维护指南:从配置优化到 MySQL 实战运行
mysql·adb·docker
muxin-始终如一24 分钟前
MySQL分区分表实现方法详解
数据库·mysql·adb
奥尔特星云大使29 分钟前
mysql高可用架构之MHA部署(三)——故障转移后邮件告警配置(保姆级)
mysql·dba·高可用·mha·邮件告警
Tomorrow'sThinker32 分钟前
第三章 · 数据库管理与视频路径获取
数据库·oracle
IndulgeCui1 小时前
【金仓数据库产品体验官】Mycat适配KES分库分表体验
数据库
长安城没有风1 小时前
从入门到精通【Redis】初识Redis哨兵机制(Sentinel)
java·数据库·redis·后端
玉面小白龍(peng)1 小时前
sql优化进阶
数据库
Adorable老犀牛1 小时前
Linux-db2look创建表结构详细参数
linux·数据库·db2