首页 > 数据库 >Mysql为什么要分表

Mysql为什么要分表

时间:2024-07-11 13:26:04浏览次数:14  
标签:为什么 分库 性能 查询 索引 Mysql 分表

为什么要分表

昨天面试,面试官我了一些Mysql分库分表的问题,我发现很多我都不知道。我仅仅知道最基础的分表机制。至于到底为什么分库分表,分库分表之后的事务我都不知道。

问到为什么分表,我说因为数据库单表数据量最合适两千万,再多可能会导致索引的层数增加。但是经过面试官追问后,我发现似乎索引的层数并不会增加。
面试结束后,我又研究了一下这个问题,发现我忘了一个关键的点,索引的结点是按页组织的,就是说根节点就是一个页的大小。这就是关键点,之前学习这块的时候我是记得的,太久不复习导致忘了这点。正所谓学而时习之。下面具体说说这个问题。

Mysql默认引擎InnoDB中,页的默认大小是16k。也就是说我们的根节点是一个页,按照b+树结构,他还要存储子结点的指针,能存的子节点指针是有限的。同时我们的叶子结点也是一个页,叶子结点能存放的记录行数等于一个页能存的记录行数。知道了这些前提条件我们就可以通过简单计算来做一个验证。
这里借用一下小林coding画的索引结构的图,如果对索引不熟悉的可以去看他的文章,我这里主要还是剖析一下我上面说的那个单表数据存储数量的问题。https://xiaolincoding.com/mysql/index/page.html
在这里插入图片描述
我们可以看到非叶结点存放的结构是多个 索引项+指针。我们讨论主键索引,对于主键索引,就是 主键值+指针。设主键类型为bigint,占8字节,innodb中一个指针6字节。6+8=14字节。同时页的默认大小是16k。我们就可以计算,一个页中可以存放多少个这种 主键值+指针的组合。16384/14=1170.2(这里16k我差点按16000来算了,低级错误,实属不该)。相当于一个页能存放1142个这样的组合。他们每个中都含有一个指针,指向子结点。对于一个三层的树,则为1170117016k=21,913,098k。这就是最终第三层数据页所能存放的数据量,一般单条记录大小为1k。则对应三层b+树大约2000万条记录。当然根据平均记录大小的不同,三层索引能容纳的记录数也不同。这个计算是相当粗略的,因为页本身还有头部。不过在数据量级上不会有差别。同时也能计算出四层索引约能存放300亿条数据。
写到这里我突然有个疑问,即使超过2000万,最后变成四层索引,也仅是多加了一次磁盘io,难道真的会因为这个导致所谓的查询性能大幅下降吗?具体多一次io的性能损耗就要落到磁盘性能上了,就有些跑题。在网上看到很多人做了实验,确实在超过2000万行时,查询性能会下降。倘若不是因为磁盘io,那么还可能是哪些原因呢?

我找到了一篇英文文章说了这个问题。
https://yishenggong.com/2023/05/22/is-20m-of-rows-still-a-valid-soft-limit-of-mysql-table-in-2023/
文章观点是所谓2000万的数据是多年前在hdd(传统硬盘)上做出的判断,当下多使用SSD(固态硬盘)这个结论已经立不住了。因为对于传统磁盘,一次磁盘io要很久,多一次都是很大的性能损失。而对于SSD来说,磁盘IO的速度已经是可以接受的了。
具体的实验可以看一下这篇文章,作者写的很清楚,我觉得没必要做重复性工作再把作者的实验拿出来在复述一遍。
我简单说一下这篇文章的结论:

  1. Innodb_buffer_pool大小/表大小决定了性能是否会降级。
  2. 对于是否分表来说,更可靠的指标是查询所需时间和缓冲池命中率,如果查询始终命中缓冲区,不会出现任何性能问题。
  3. 除了分表外,增加Innodb_buffer_pool的大小或者数据库内存也是一种对抗性能下降的选择。
  4. 如果可能,请避免在生产环境中select *,因为在最坏的情况下,这会导致 2 次索引树查找。
  5. 考虑到SSD现在很流行,20M行并不是MySQL表的一个非常有效的软限制。

感悟

看完这篇文章我突然明白过来,分表只是手段,目的是为了提高查询性能,它并不是实现目的的唯一途径。提高Innodb_buffer_pool大小也是手段。我对Mysql的查询优化策略并不了解,仅仅了解一些简单的查询原则。网上略微搜了一下,感觉是一门很大的学问,这部分是比较重要的,我觉得可以是一个Mysql进阶的学习方向。

回到最开始的问题,为什么要分表?

  1. 首先表数据量过大,查询的数据量也很大时,你的Innodb_buffer_pool大小必然是无法容纳那么大量的数据的,所以命中率低,很影响性能。
  2. 其次索引高度增加到第四层,确实是会增加一次磁盘io,确确实实是有性能损耗的。
    暂时只能想到这两个原因,欢迎大伙补充。
    重要的还是性能问题。如果没有性能问题,你一个表一亿数据不分表我觉得也没问题。

后续

对于分库分表,会有很多的问题:
分布式事务问题
跨节点关联查询
主键重复
分片算法
使用什么中间件
等等

本来打算一篇文章写完,结果仅仅写完分表的原因就花了好久。标题也从Mysql分库分表变成了Mysql为什么要分表。后面在写这些问题吧。

昨天面试官就问了分库分表会有哪些问题,我发现自己确实不知道,只知道数据迁移这个问题。面试官人很好,教我想把分库分表写在简历上作为亮点,应该深入的研究一下这些问题,中间件是怎么解决的。我发觉自己项目中仅仅简单对数据库表做了分表,对于更深层次的东西确实缺少了解。这块应该是接下来的学习重点。
对于一些技术来说还是不要不求甚解,明白更深层次的东西才是真正属于你的知识。感谢昨天的面试官。

文章欢迎大伙批评指正。

标签:为什么,分库,性能,查询,索引,Mysql,分表
From: https://blog.csdn.net/qq_42939279/article/details/140347353

相关文章

  • 【笔记】mysql主从复制
    数据的读写都放在一台数据库上会导致该数据库压力过大,且如果此数据库损坏丢失无备份会造成损失故:设置两台(这里以两台为例)主数据库负责写入从数据库负责读取从数据库从主数据库那里取数据进行数据同步开干!(一)在VM准备好两台虚拟机创建虚拟机真的很简单选择典型之后......
  • 使用夜莺和 Categraf 快速建设 MySQL 监控
    之前翻译过一篇文章,介绍 MySQL监控的一些原理,本文侧重实操,使用夜莺v7.beta12.1版本为大家做一个演示,采集器使用Categraf,先看一下最终仪表盘效果:下面开工。1.安装夜莺和Categraf夜莺的安装可以参考 夜莺官方文档,Categraf的安装可以参考 Categraf官方文档。这里就不赘......
  • 13 mysql高级查询
    完整的查询sql语句selectselect选项字段列表fromtable表数据源wherewhere条件groupbygroup分组条件havinghaving条件orderbyorder排序limitlimit限制select选项:all默认,可以省略,表示保存所有查询的结果distinct:去重,去除重复记录(所有的字段都相同才是重复的......
  • (免费领源码)Java/Mysql数据库+09536 SSM爱心捐赠物资维护系统,计算机毕业设计项目推荐上
    摘要随着信息技术的快速发展,计算机应用已经进入成千上万的家庭。随着物资数量的增加,物资库存管理也存在许多问题。物资数据的处理量正在迅速增加,原来的手工管理模式不适合这种形式。使用计算机可以完成数据收集、处理和分析,减少人力和物力的浪费。需要建立爱心捐赠物资维护系......
  • Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和
    场景存储过程存储过程是一组为了完成特定功能的SQL语句集合。使用存储过程的目的是将常用或复杂的工作预先用SQL语句写好并用一个指定名称存储起来,这个过程经编译和优化后存储在数据库服务器中,因此称为存储过程。当以后需要数据库提供与己定义好的存储过程的功能相同的服务时,......
  • MYSQL——帆软连接报错
    2024/07/111.报错2.报错原因3.解决办法4.参考1.报错错误代码:11300001数据集配置错误<br>Query:<br>Unknowninitialcharactersetindex'255'receivedfromserver.Initialclientcharactersetcanbeforcedviathe'characterEncoding'property.日志里......
  • 成为MySQL DBA后,再看ORACLE数据库(十三、物理备份)
    前面总结了ORACLE的逻辑备份,本文来总结以下ORACLE的物理备份。数据库的备份一般分为冷备份和热备份,其中冷备份是指将数据库彻底关闭后进行的一致性备份,由于需要关停数据库所以在实际应用中很少用到冷备份。而热备份是指在数据库运行的同时对数据库进行备份,本文主要总结的是ORACLE......
  • Python中的元组:为什么它们比列表更快?
    引言        在Python编程语言中,数据结构是存储和组织数据的强大工具。Python提供了多种内置数据结构,如列表(List)、字典(Dictionary)、集合(Set)等。元组(Tuple)是其中一种非常重要的数据结构,它因其独特的特性和用途,在Python编程中占有一席之地。一、元组的定义     ......
  • 宋红康MySQL笔记
    MySQL数据库入门到大牛,mysql安装到优化,百科全书级,全网天花板https://www.bilibili.com/video/BV1iq4y1u7vj?p=43&vd_source=ecbebcd4db8fad7f74c518d13e78b165HAVING的使用#练习:查询各个部门中最高工资比10000高的部门信息#错误的写法:SELECTdepartment_id,MAX(salary)FROMem......
  • 基于SpringBoot + SpringCloud+ElasticSear的在线教育管理系统设计与实现(MySQL、Mongo
    本项目适合做计算机相关专业的毕业设计,课程设计,技术难度适中、工作量比较充实。完整资源获取点击下载完整资源1、资源项目源码均已通过严格测试验证,保证能够正常运行;2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通;3、本项目比较适合计算......