为什么MySQL数据库单表建议最大2KW数据?

news2024/12/29 11:00:59

文章目录

  • 为什么MySQL数据库单表建议最大2KW数据?
    • 一、 Innodb 存储引擎
      • 1、数据存储
      • 2、数据页的结构
    • 二、 B+ tree 结构
    • 三、 B+ 树存放数据的行数

为什么MySQL数据库单表建议最大2KW数据?

  我们经常会听到一种说法,在MySQL中,数据库单表建议最大两千万条数据,如果超过了,性能就会下降得比较厉害。那么2000w这个值的依据是什么?怎么算出来的呢?今天就带大家来研究一下。

一、 Innodb 存储引擎

1、数据存储

  大部分场景我们都是使用 Innodb 存储引擎,在 MySQL 的 Innodb 引擎中,每一张表在磁盘上都会有对应的一个.ibd文件(Innodb data 文件),这个文件叫表空间。在表空间中,数据是以数据页的形式进行存储的,每一页只有 16KB 的大小。

在这里插入图片描述

三个重要的最小单元:

  • 磁盘扇区:磁盘上存储数据最小单元是扇区,一个扇区的大小是 512 字节;
  • 块 (block):文件系统(例如EXT4)最小单元是块 (block),一个block 块的大小是 4KB;
  • 页(Page) :Innodb 存储引擎 的最小储存单元——页(Page),一个页的大小是 16KB。
    在这里插入图片描述
      由于文件系统(例如EXT4)的最小单元是块 (block),一个block 块的大小是 4KB,所以,假设一个文件大小只有1个字节,那么这个文件在磁盘上,还是不得不占4KB的空间。
      Innodb 的所有数据文件(后缀为 ibd 的文件),也是存储在磁盘的,当然也是由block组成,所以,Innodb 的所有数据文件,全部都是 16384(16KB)的整数倍。
      在 MySQL 中, InnoDB 页的大小可以通过命令查看,show variables like ‘innodb_page_size’。

2、数据页的结构

在这里插入图片描述

  行数据 record 被分成好多份,放到各个页里了,为了唯一标识具体是哪一页,那就需要引入页号(其实是一个表空间的地址偏移量)。同时为了把这些数据页给关联起来,于是引入了前后指针,用于指向前后的页,这些都被加到了页头里,页头 120 B 字节。

  页需要支持读写,16KB 说小也不小,写一半电源线被拔了也是有可能发生的,所以,为了保证数据页的正确性,还引入了校验码,这个被加到了页尾,页尾 8 B 字节。

  剩下的空间才是用来放行数据 record 的,如果行数据 record 行数特别多,进入到页内时会挨个遍历,效率也不太行,所以,为这些数据生成了一个页目录。具体实现细节不重要,只需要知道,它可以通过二分查找的方式将查找效率从 O(n) 变成 O(logn)。

数据页的结构:在这里插入图片描述
在这里插入图片描述

在数据插入的过程中,数据页的变化如下:

在这里插入图片描述

(1)申请新的数据页;
(2)此时并没有User Records这个部分,当我们插入一条记录时会从Free Space也就是尚未使用的存储空间中申请一个记录大小的空间划分到User Records中用于记录的存储;
(3)当Free Space部分的空间全部被User Records部分替代掉之后,也就意味着这个页使用完了;
(4)继续有新的记录插入;
(5)重新申请新的页。

二、 B+ tree 结构

  如果想查找一条行数据 record,可以把表空间里每一页查出来,再遍历里面的行数据 record ,挨个判断是不是我们要找的。行数小的时候,这么操作也没啥问题。行数多了,性能就慢了。于是为了加快搜索,可以在每个数据页里选出主键 id 最小的 record,而且只需要它们的主键 id 和所在页的页号,将它们组成新的 record,放入到一个新生成的一个数据页中,这个新数据页跟之前的页结构没啥区别,大小还是 16KB。但为了跟之前的数据页进行区分,数据页里加入了页层级(Page Level)信息,从 0 开始往上算,于是页与页之间就有了上下层级的概念,页跟页之间看起来就像是一棵倒过来的树,也就是我们常说的 B+ 树索引。

  所有的数据以数据页的形式进行存储,为了增加查询效率,数据页与数据页之间是以 B+ 树的形式进行关联的。页的页号并不是连续的,它们在磁盘里也不一定是挨在一起的。使用二分查找,时间复杂度从 O(n) 变成 O(logn)。

在这里插入图片描述

  • B+ 树的叶子节点存放的是实际存储的行记录数据,数据页;
  • B+ 树的非叶子节点存放的是索引内容(子节点中,页的第一条数据的主键ID + 页的地址),索引页;
  • B+树的每一层代表一次磁盘IO(性能损耗的点)。

三、 B+ 树存放数据的行数

在这里插入图片描述

设:
  非叶子结点存放的指向其他数据页的指针数量为 X ;
  叶子节点存放的行数据数量为 Y ;
  B+ 树的层数(高)为 Z 。

则:

  B+树能存放的总行数 = (X ^ (Z-1)) * Y

代入计算:

  一个数据页 16KB ,扣除各种信息,可用的空间约为15KB。

  假设主键 ID 为 bigint 类型为 8 byte,页号占用4 byte,非叶子节点里的一条数据是 12 Byte 左右,则:X = 15*1024/12 ≈ 1280,指向 1280 个新的数据页。

  Y 是数据页中能容纳的最大行记录数量,所以与实际存储的行记录的大小有关,假设一条行记录占用的空间大小为1KB,则:Y = 15。

  假设B+树是两层,那 Z = 2,则总行数 = (1280 ^ (2-1)) * 15 ≈ 2 W。

  假设B+树是三层,那 Z = 3,则总行数 = (1280 ^ (3-1)) * 15 ≈ 2.5 KW。

  这个数据是根据每条行记录的大小为 1KB 时估算而来的,而实际情况中并不一定是这个值,所以说,最大建议行数2000w这个值只是一个建议,并非一个标准。

  B 树,B 树叶子结点和非叶子结点上都放数据表行数据。每个数据页 16KB,掐头去尾每页剩15KB,假设一条数据表行数据还是占 1KB,就算不考虑各种页指针的情况下,也只能放个 15 条数据,数据页的扇出明显变小了。计算可承载的总行数的公式也变成了一个等比数列。其中 Z 还是层数的意思。
  15 + 15^2 +15^3 + … + 15^Z
  为了能放两千万左右的数据需要 Z>=6,也就是树需要有 6 层,查一次要访问 6 个页,假设这 6 个页并不连续,为了查询其中一条数据,最坏情况需要进行 6 次磁盘 IO。而 B+ 树同样情况下放两千万数据左右,查一次最多是 3 次磁盘 IO。磁盘 IO 越多则越慢,这两者在性能上差距略大。因此,B+ 树比 B 树更适合成为 MySQL 索引。

  在 InnoDB 中 B+ 树高度一般为1-3层,它就能满足千万级的数据存储。查询数据时,每加载一页(page)代表一次IO,所以通过主键索引查询通常只需要1~3次 I/O 操作即可查找到数据。

  MySQL 都有缓存, B+ 树高度为 3 时,第 1 层和第 2 层的数据都在缓存中,查询只需要一次 I/O 操作,速度很快,但是当数据超出 2KW 时, B+ 树层高会增加,需要再多一次 I/O 操作,查询效率就急速下降了。所以MySQL数据库单表建议最大2KW数据。

InnoDB表必须有主键,并且推荐使用整型的自增主键!!!为什么?
  InnoDB使用聚簇索引将主键组织到一棵B+树中,聚簇索引默认是主键,如果表中没有定义主键,InnoDB 会选择一个唯一的非空索引代替,如果连这样的索引没有,InnoDB 会生产一个隐藏列 Row_id 来充当默认主键,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/562161.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Security 中的 CSRF 攻击是什么?如何防止它?

Spring Security 中的 CSRF 攻击是什么?如何防止它? 什么是 CSRF 攻击? CSRF(Cross-Site Request Forgery)攻击是一种常见的网络安全威胁,也称为“跨站请求伪造”攻击。攻击者可以通过某些手段&#xff0…

SpringBoot整合RabbitMQ及其原理分析

上一篇&#xff1a;RabbitMQ基础知识 1、相关依赖 这里无需指定版本号&#xff0c;让其跟着SpringBoot版本走。本示例使用SpringBoot版本号为2.7.10。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-…

SaaS系统平台,如何兼顾客户的个性化需求?

在当今数字化的商业环境中&#xff0c;SaaS系统已经成为企业运营的重要组成部分之一。 SaaS系统平台的好处是显而易见的&#xff0c;可以将业务流程数字化&#xff0c;从而帮助企业提高效率并节省成本。 但是&#xff0c;由于每个企业的业务都不尽相同&#xff0c;所以在选择Sa…

GuLi商城-前端基础ES6

ES6 ES6全称ECMAScript6.0是JavaScript语言的下一代标准。 ECMAScript是浏览器脚本语言的规范&#xff0c;而我们熟悉的各种js语言&#xff0c;如JavaScript则是规范的具体实 现。 新建一个ES6文件夹&#xff0c;shift!按着不动&#xff0c;回车&#xff0c;可以快速生成模…

图神经网络:(处理点云)PPFNet的实现

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook和有关文献。超链。提取码8848。 文章目录 前言文献阅读代码实操历史遗留问题 前言 本篇文章接上一篇文章…

【LeetCode: 410. 分割数组的最大值 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

这七种常见的路由协议,每一个网络工程师都应该知道!

你好&#xff0c;这里是网络技术联盟站。 路由协议是网络中非常重要的一个概念&#xff0c;它负责将数据包从源节点传递到目的节点。路由协议定义了网络中不同路由器之间的通信规则和数据传输方式&#xff0c;以便有效地将数据包从源地址传输到目标地址。在网络领域中&#xf…

基于无人机辅助边缘计算系统的节能卸载策略

源自&#xff1a;《系统工程与电子技术》 作者&#xff1a;余雪勇 朱烨 邱礼翔 朱洪波 摘 要 针对复杂地形中地面基础设施无法有效提供可靠通信和密集算力的问题,首先提出一种基于无人机(unmanned aerial vehicle, UAV)托管计算资源的卸载方案。考虑用户终端的计算需…

提升网站访问性的10个步骤优化

第一步,检查 不允许空,不允许过长,简洁明了。 是第一个可以访问到内容的元素,所以一定要非常重视。当用户切换浏览器Tab标签的时候,一定最先听到 标记的内容。Title一定要能代表当前页面的主题。这里的要求和SEO最佳实践几乎一致。 第二步,提供文字替代方案。 走查网页…

【LeetCode】238. 除自身以外数组的乘积

238. 除自身以外数组的乘积&#xff08;中等&#xff09; 方法一&#xff1a;左右乘积列表 思路 除了 nums[i] 以外各元素的积&#xff0c;就等同于 nums[i] 左边元素的乘积 * 右边元素的乘积&#xff0c;因此&#xff0c;我们可以计算出两个乘积列表 &#xff0c;最后再经过一…

2023-05-23 题目

1、在java中定义一个无参的构造方法的作用&#xff1a; 在java程序执行子类的构造方法之前&#xff0c;如果是没有super()来调用父类的特定的构造方法&#xff0c;则会调用父类中没有参数的构造方法。 如果java中没有定义无参的方法&#xff0c;且没有指定super()方法&#x…

深眸科技探索AI机器视觉技术,助力密封圈缺陷识别检出率达99.8%

密封圈作为一种具有良好性能的密封材料&#xff0c;在工业领域具有极其广泛的应用&#xff0c;在汽车、船舶、管道、家用电器等多行业都能看见它的身影&#xff0c;广阔的市场需求促就密封圈产业的蓬勃发展。 密封圈属于大批量生产&#xff0c;在生产过程中难免会出现瑕疵品&a…

zabbix监控系统

一、Zabbix概述 1、使用zabbix的原因 作为一个运维&#xff0c;需要会使用监控系统查看服务器状态以及网站流量指标&#xff0c;利用监控系统的数据去了解上线发布的结果&#xff0c;和网站的健康状态。 利用一个优秀的监控软件&#xff0c;我们可以: ●通过一个友好的界面进…

vue 3.0使用 iframe 标签引入本地HTML页面,并实现数据交互

文章目录 1. 问题总结2. vue中引入html页面3. vue向html传递数据4. html向vue传递数据 1. 问题总结 最近在做vue的项目时候&#xff0c;需要引入本地html页面&#xff0c;中间遇到了很多问题&#xff0c;费时又费力&#xff0c;因此记录下来&#xff0c;以备不时之需&#xff…

顺序表 ArrayList

目录 1. 概念 2. ArrayList集合框架图 3.ArrayList常见的方法 4. 自己实现ArrayList&#xff08;Integer&#xff09; 4.1 ArrayList构造 4.2 ArrayList容量的扩容 4.3 判断空满 4.4 pos坐标是否合法&#xff08;含有&#xff09; 4.5 ArrayList的增删元素 4.6 包含元…

操作系统原理 —— 死锁的概念(十七)

什么是死锁 什么是死锁&#xff0c;如果你是个程序员&#xff0c;那么这概念肯定是不陌生的&#xff0c;死锁通常是指&#xff0c;在并发环境下&#xff0c;各个进程因竞争资源而造成一种相互等待的现象&#xff0c;导致的结果就是各个进程都处于阻塞状态&#xff0c;无法往下…

老司机解读香农定理、奈奎斯特定理、编码与调制

工程师都会考虑一个问题&#xff1a;信道上到底可以传输多大的数据&#xff0c;或者指定的信道上的极限传输率是多少。这就是信道容量的问题。例如&#xff0c;在xDSL系统中&#xff0c;我们使用的传输介质是仅有几兆带宽的电话线&#xff0c;而上面要传送几兆、十几兆甚至几十…

cuda编程学习——基础知识介绍!干货向(三)

本文主要内容为介绍CUDA编程前的一些基础知识 参考资料&#xff1a; 高升博客 《CUDA C编程权威指南》 以及 CUDA官方文档 文章、讲解视频同步更新公众《AI知识物语》&#xff0c;B站&#xff1a;出门吃三碗饭 1&#xff1a;并行计算 并行程序可以分为 指令并行&#xff1…

还在使用System.out+System.currentTimeMillis打印耗时?Xrebel是你不可或缺的神器!

1、概述 在Java应用程序中&#xff0c;性能是至关重要的。由于Java应用程序通常在高并发环境中运行&#xff0c;并处理大量数据&#xff0c;因此需要确保其能够高效地运行。为了帮助开发人员更好地实现Java应用程序的性能调优&#xff0c;ZeroTurnaround推出了XRebel。 XRebe…

测试用例的设计方法(全)

等价类划分方法 一.方法简介 1.定义 是把所有可能的输入数据,即程序的输入域划分成若干部分&#xff08;子集&#xff09;,然后从每一个子集中选取少数具有代表性的数据作为测试用例。该方法是一种重要的,常用的黑盒测试用例设计方法。 2.划分等价类&#xff1a; 等价…