看到使用分库分表来解决性能问题的时候心里总是不能太理解。
如果同事发生大量请求的时候,损害性能的是硬盘的随机读。那么分库分表也没有对性能的瓶颈进行“分治”啊。
应该的做法是使用一块新的硬盘来创建分库。但是基本的文章都没有提到这点。而且基本上也不会有公司这么做,毕竟现在一快硬盘在1T所有,一个数据库肯定占用不了这么多地方。而且程序员在申请数据库的时候,也没有办法说明使用不同的硬盘来部署这数据库。而且也不知道部署在这些硬盘上有没有大量的随机读。
还有好多人都觉得MYSQL数据库有性能问题,在单表超过500W或者2000W的时候就要分库分表。我觉得从MYSQL的数据结构来说,应该不存在这些问题。(好多帖子说是避免树高过高。)其实树高增加一层会增加一个数量级的数据存放量。如果通过分库分表来减少树高,可以累死程序员。这也不是程序员应该考虑的。MYSQL只要缓存一个顶级节点pageCache就相当于做了“分库分表”了。所以一直认为分库分表是个伪命题。
下面使用程序来做一下实验来证明自己的想法。
在测试环境Linux系统下安装mysql 5.7.41。本地使用java 8 为客户端代码。
实验一:单表操作
1)创建数据库test
2)创建T_PERSON表
3)使用Java JDBC 批量插入100,000,000条数据,4096为一个批次。总共耗时为:2150秒。
实验二:分表不分库
实验三:分库分表
数据库 |
表 |
表大小 |
连接数 |
Batch |
总共插入数据 |
耗时时间(秒) |
|
实验1 |
1 |
1 |
8.4G |
1 |
4096 |
100,000,000 |
2150 |
实验2 |
1 |
8 |
1.1G |
1 |
4096 |
100,000,000 |
|
实验3 |
8 |
1 |
1.1G |
8 |
4096 |
100,000,000 |
|
实验1 Postgre |
1 |
1 |
NA |
1 |
4096 |
100,000,000 |
读取实验
客户端环境,java8, spring-boot 2.6.6, sharing-sphere 3.1.0
实验一:使用上诉实验一的环境。共使用16个Connection。使用jmeter进行压力测试10 Thread,QPS 为826, 20 thread 889.
实验二:10 thread 833, 20 thread 944
实验三:10 thread 848, 20 thread 902
数据库 |
表 |
连接数 |
10 threads |
20 threads |
|
实验1 |
1 |
1 |
16 |
826 |
889 |
实验2 |
1 |
8 |
16 |
833 |
944 |
实验3 |
8 |
1 |
2 |
848 |
902 |
跟预想的是一样的,分库分表并不能提高性能。
读取实验二
客户端环境,java8,使用多线程,JDBC来测试性能。
数据库 |
表 |
连接数 |
测试结果 |
测试结果 |
|
实验1 |
1 |
1 |
8 |
5304.73 |
6086.77 |
实验2 |
1 |
8 |
8 |
7140.63 |
6467.98 |
实验3 |
8 |
1 |
8 |
5832.50 |
6614.85 |
实验1 |
1 |
1 |
16 |
14096.30 |
13497.41 |
实验1 |
1 |
1 |
24 |
18694.14 |
17823.77 |
实验1 |
1 |
1 |
32 |
19104.83 |
21274.47 |
也证明了分库分表不能明显提高性能,但是增加并发数可以有效的提高性能。因为mysql没有reactive的driver,就没有测试。
PS: 里面涉及大大量的取余的计算,我特意把除数都设置成2的几次幂,我以为编译器会可以帮我优化。但是查看class代码并没有进行优化。
然后又使用javac –O 测试,已经没有进行优化,不知道为什么。
问了一下ChatGPT,他就可以做出优化的解释。
也使用了一下https://www.cnblogs.com/BetterCallSaul/p/MySQL.html 提到的查看树高的方法。我的数据库使用的10W的时候是2层,但是到了20W就是3层了,1亿的时候也是三层。
ps: innodb_page_size 16384 (16K)
数据量 |
树高 |
100000 |
2 |
200000 |
3 |
300000 |
3 |
100000000 |
3 |
PS: 该文章是针对网上一些MYSQL性能不好,或者单表500W或者2000W需要进行分表。或者是为了减少树高的一些观念的看法。我觉得这些观点并不应该成为分库分表的主要目的。
摘自《阿里的开发手册》 。
Mysql单表最大记录是多少_mysql单表数据量_怎么又有bug单的博客-CSDN博客mysql单表最大记录数不能超过多少?https://blog.csdn.net/GBS20200720/article/details/125344782
分库分表的目的from ChatGPT
分库分表是一种常见的数据库水平扩展方案,它的主要目的是解决单一数据库的性能瓶颈和容量限制问题,提高系统的扩展性和可用性。
在单一数据库中,当数据量增长到一定程度时,会面临性能瓶颈和容量限制的问题。而分库分表可以将数据水平拆分到多个数据库或数据表中,每个数据库或数据表只负责一部分数据的存储和查询,从而提高了数据库的性能和容量。同时,分库分表也可以增加系统的可用性,当一个数据库或数据表出现故障时,只会影响到一部分数据,其他数据库或数据表仍然可以继续工作,从而保证了系统的正常运行。
除了提高系统性能和容量,分库分表还可以提高数据库的可扩展性。随着数据量的增长,可以通过增加数据库或数据表的数量来扩展系统的容量和性能,而不需要对原有的数据库或数据表进行修改或扩展。
总之,分库分表是一种解决单一数据库性能瓶颈和容量限制问题,提高系统可用性和可扩展性的有效方式。但是,在实际使用中需要考虑数据一致性、查询路由、数据迁移等问题,需要谨慎设计和实施。
我还是觉得chat GPT的答案挺好的。分库分表肯定有用处,但是我们在使用的时候需要评价我们的场景,以及带来的优缺点,然后我们需要权衡这些优缺点。不要一味的听说要分库分表,或者觉得“分库分表” 很高级。