为什么 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 权限设计(二)
相关推荐
zhangjin122231 分钟前
kettle从入门到精通 第九十四课 ETL之kettle MySQL Bulk Loader大批量高性能数据写入
大数据·数据仓库·mysql·etl·kettle实战·kettlel批量插入·kettle mysql
深圳厨神40 分钟前
mysql对表,数据,索引的操作sql
数据库·sql·mysql
谁家有个大人41 分钟前
数据分析问题思考路径
数据库·数据分析
hweiyu0043 分钟前
从JVM到分布式锁:高并发架构设计的六把密钥
jvm·redis·分布式·mysql·etcd
小陈又菜1 小时前
MySQL-触发器
数据库·mysql·database·触发器
爱的叹息1 小时前
详解隔离级别(4种),分别用表格展示问题出现的过程及解决办法
数据库·oracle
平凡的小y1 小时前
MySQL内置函数
数据库·mysql
佩奇的技术笔记1 小时前
中级:MyBatis面试题深度剖析
数据库·mybatis
慕丹1 小时前
虫洞数观系列三 | 数据分析全链路实践:Pandas清洗统计 + Navicat可视化呈现
python·mysql·数据挖掘·数据分析·pandas
luluoluoa1 小时前
SQL、mySQL与SQLite简单理解
sql·mysql·sqlite