不少技术文章都直接引用了这个观点,但没说为什么?有大佬解释下这个理论依据吗?
1
zhilincom 2022-10-16 05:02:49 +08:00
听说 MySQL 单表超过 1000 万行性能会急剧下降。
|
2
akira 2022-10-16 05:39:58 +08:00
这应该是个经验数字,不一定绝对对。 但是如果你只有几十 几百万的数据,就大概率是直接用就好,不需要考虑那么多事情
|
3
dayeye2006199 2022-10-16 07:11:17 +08:00 via Android
可能和 b 树的深度,和 Page 的大小有关
|
4
wxf666 2022-10-16 07:18:44 +08:00 1
反正 20 天前,在一个 [帖子]( https://www.v2ex.com/t/882773 ) 里,有很多人反映,MySQL 单表存 1~2 亿(#11 楼 #16 #18 #19 #21 #35 )、4 亿(#27 )、10 亿(#36 )、20 亿(#28 )都没问题,查询也很快(< 10 ms ,#27 #28 )
|
5
wxf666 2022-10-16 07:20:33 +08:00
我在那个帖子里的 3 楼,也问了个类似的问题,也给出一点猜测(但没人理我。。)
|
6
chendy 2022-10-16 07:29:12 +08:00 4
1. 经验数字
2. 阿里(也许)自己有足够完善的组建处理分库分表 3. 阿里(也许)可以通过传播这个数字,卖更多的数据库或者其他服务 |
7
liuzhaowei55 2022-10-16 07:33:24 +08:00 via iPhone 1
备份、恢复数据的难度,太大了也是灾难
|
8
GTim 2022-10-16 08:14:19 +08:00
很多业务,估计一个小时就要分一次表了
|
9
makelove 2022-10-16 08:38:33 +08:00
才 500 万,哪怕机械硬盘时代都毫无问题,更别提现在的高速 SSD
|
10
jorneyr 2022-10-16 08:55:03 +08:00
分库分表没那么好玩,应用端需要精心设计,不能像单库那样随心所欲的写 SQL 。
|
11
Maboroshii 2022-10-16 08:56:04 +08:00 via Android
之前有人说是 2000w 行,查了一下是索引数深度的效率相关
|
12
sadfQED2 2022-10-16 08:58:27 +08:00 via Android
@jorneyr 可以加一个 db proxy 层,这一层屏蔽分表分库细节,你代码里面依然可以当单表使用,随心所欲的写 sql 。
|
13
bthulu 2022-10-16 09:10:02 +08:00 1
那是说的机械硬盘经验值, 还是偏保守的那种.
现在的 M.2 SSD, 三星 980PRO, 随机 4k 读写速度是普通机械的 500 倍往上, 同样的, 500 万*500=25 亿, 也就是说, 保守点估计 25 亿行数据再考虑分库分表, 胆子大一点的, 100-1000 亿行数据以上再去考虑这个问题. |
14
jorneyr 2022-10-16 09:11:32 +08:00
@sadfQED2 分布式数据库一般都有 DB Proxy 的,但是 SQL 落到多个库,数据量大的时候,Proxy 每个节点都取数据来处理的时候,一是慢,二是容易内存超量,例如有 1024 个节点,要查询 1000 行,不巧写的 SQL 没有分片键,那么就要去这 1024 个节点上各自都获取 1000 行数据,Proxy 得到 1024 * 1000 行数据进行 Merge Sort ,然后再判断一次取出合适的 1000 行。
最直观的是使用 Sharding Sphere ,或者看看 TDSql 等的设计文档,没那么自由。 |
15
Biggoldfish 2022-10-16 09:15:11 +08:00
一张 table 2GB 就性能下降到不可接受了,怕是在用十年前的 DB 吧
|
16
cooper 2022-10-16 09:17:11 +08:00 7
|
17
lmshl 2022-10-16 11:12:45 +08:00
|
18
lmshl 2022-10-16 11:19:09 +08:00
我怀疑写八股文和背八股文的人不懂什么是 O(log(n)),就硬背树深了一层
健康项目中:低效率查询,未命中索引的查询应该在 Code Review 阶段被驳回的。过早期的分库分表还会极大提高总持有成本,百害而无一利。因为只需要简单的主从读写分离架构就可以支撑到数万 TPS 了。 |
19
dog82 2022-10-16 11:53:07 +08:00
这应该是个经验之谈。主要是看表怎么用,如果仅仅是主键查询 10 亿都不要分表。
|
20
ration 2022-10-16 11:58:36 +08:00 via Android
什么数据库,什么版本,硬件性能咋样,如果是 mysql 用的是什么引擎,条件不充分都是空谈。我觉得测试之后才能有结果,真正实践的话也要对数据库进行测试。
|
21
reter 2022-10-16 12:26:49 +08:00
物理定律还有适用条件呢,更何况数据库的访问模式不同,硬件、软件也会不断地迭代和优化
|
22
dog82 2022-10-16 12:39:46 +08:00
分表并不会让事情变得更简单,仅仅是用逻辑复杂度代替空间复杂度而已
|
23
murmur 2022-10-16 12:43:51 +08:00
@lmshl 是不是民科不重要,重要的在于程序员的素养,如果考虑到外包团队普遍拉垮的质量,以及 java mysql 这些在企业应用中的高占比,我赞同 500w 分表
|
24
JohnBull 2022-10-16 13:53:03 +08:00
应该没这么夸张。
自建的文件元数据索引表没能正确处理符号链接 loop ,结果整出来几百 G 的表,直到手工执行 count(*)的时候才发现不对劲,其它操作基本无感 |
25
yohole 2022-10-16 14:11:21 +08:00
应该是性能目标不一致造成的错觉
[查询没有问题] 这个本身就很主观的东西,不同企业不同场景对 [查询没问题] 的定义可以差很大的啊 其他企业敢说自己的查询目标要求与阿里场景和要求一致吗? |
26
iseki 2022-10-16 14:34:03 +08:00
阿里的技术手册,其他实体应当仅供参考。
|
27
0576coder 2022-10-16 14:43:46 +08:00
之前生产环境有张过亿的表,其实表大了 查询还好,插入更新的时候,cpu 磁盘都会飙升,而且索引建的不科学的话,大表真的是噩梦,大表再数据插入的时候,还不稳定,时间慢,所以我感觉查询并不是分库分表的原因
这种情况在数据千万级别的时候就慢慢开始显现,但是这个 500W 的数字我也不知道怎么得出的 |
28
mmdsun 2022-10-16 14:52:20 +08:00
过亿有索引的查询肯定没问题。
有没有人试过修改、更新、和连表的性能? |
29
0576coder 2022-10-16 15:16:56 +08:00
@mmdsun insert 跟 update 的时候会有问题 如果 update 的范围过大 可能该表就卡住了一样 而且时间还不稳定 尤其是索引多一点的时候 简直是噩梦
|
30
Leviathann 2022-10-16 15:35:40 +08:00
查单条肯定随便过亿,其他操作我擦我不好说
|
31
romisanic 2022-10-16 15:39:46 +08:00
实际工作中遇到过表数据超过两千万的情况,没有分表,是公司内 IM 的聊天记录。
结论是:查询、插入,以及主键更新,甚至索引做的不错,条件查询、翻页也还可以。 但是:开发新功能时,表结构变更,一个不注意,就是灾难。变更一次锁表 20 分钟。 |
32
Valid 2022-10-16 15:52:48 +08:00
表设计的垃圾才需要
|
33
Jooooooooo 2022-10-16 15:53:56 +08:00
这当然是经验只谈.
几百万的表, 单表查基本没事. 越大单表风险越大, 还是趁早拆. |
34
victorc 2022-10-16 16:58:24 +08:00
它就是随便一说,不要这样机械,一旦启用分表,你的程序也要对应的修改,分表的好处是:系统具备横向扩容的能力. 流量大幅度上涨之后,加点机器就能抗住,如果没有这个需求就不需要扩
只要硬盘够大,单表存放数量随便 |
35
shiny 2022-10-16 17:02:40 +08:00
小马过河,自己趟一趟才知道深浅。索引做得如何、SQL 复杂度、硬件配置、每行数据的数据量都会对结果有影响。有十几亿记录数的表也跑得欢,也遇到过百万的表就已经很慢。
|
36
tohuer00 2022-10-16 18:10:24 +08:00
分表分库这些都是有代价的,分了以后业务开发难度会明显增大,越复杂的业务越是如此。
很多公司负责技术架构的人并不参与业务开发,说得不好听,为了自己的 KPI ,纸上谈兵拍脑袋定方案,害人不浅。 分不分表,怎么分,都要看具体业务和原有设计。 |
37
HankLu 2022-10-16 18:22:38 +08:00
超过 500 万行或 2GB 才推荐,也就是说不超过 500 万行或 2GB ,不推荐分表,因为完全没有这个必要。
|
38
cbdyzj 2022-10-16 19:19:45 +08:00 via Android
我们公司以前是 800w 行,但实际生产上也有超过 4000w 行的表跑着
|
39
someonedeng 2022-10-16 19:27:50 +08:00
甚至没提硬件。。就嗯背八股
|
40
aptupdate 2022-10-16 19:51:47 +08:00 via iPhone
我记得 oracle 是 1 亿,mysql 不至于这么拉胯吧?
|
41
sean424 2022-10-16 21:01:36 +08:00
12 年的时候,mysql 免费版 大概 600 多万 数据是个分界线
|
42
keakon 2022-10-16 21:21:26 +08:00
InnoDB 的一页默认是 16KB ,其中有 100 多字节是头部等不用于存储数据的,这里先忽略。
索引页的每行要存储一个主键(假设是 int ,4 字节)和一个页号( 4 字节),共计 8 字节。即一页最多存储 2K 条。 以一个 3 层的 B+ 树来计算,前两层是索引页,最多索引 2K * 2K = 4M 个节点。 假设表的每行占用的空间是 1KB ,那么一个数据页(叶子节点)最多存储 16 条数据,所有节点共可以存储 64M 条数据( 64GB 大小)。 超过这个量时,要用 4 层的 B+ 树,那么 IO 次数就至少多出 1/3 ,索引也很难全放在内存中,肯定会大幅影响性能。 但是题目中提到的 500M 行和 2GB 并不是一个固定值,如果主键和每行占用的空间较小,就能存放更多的页。甚至你还能修改 innodb_page_size ,配置成更大的页,以在一页中存储更多行(但是可能造成 IO 的浪费,因为每次至少读一页)。 |
43
lazyfighter 2022-10-17 09:26:59 +08:00
@keakon 非常赞
|
44
sun1991 2022-10-17 09:27:34 +08:00
之前一个人能搞定, 分表后需要一个团队维护. 对部门有利.
|
45
daoqiongsi1101 2022-10-17 13:07:02 +08:00
我们存了十几亿数据,看你怎么查,不是所有查询都会很慢
|
46
Seulgi 2022-10-17 14:13:57 +08:00
阿里人家数据库实例是什么规格都没给你说, 你怎么确定自己的实例规格要按照 500w 或 2GB 来呢, 阿里的技术手册, 就看看就行吧. 经验值始终要去躺一次才知道什么效果, 没必要强硬生套.
|
47
cubecube 2022-10-17 14:27:53 +08:00
@wxf666
1. 十年前的 mysql 的确不太行( 5.7 之前) 2. 十年前的 CPU 性能瓶颈也很大,不分库存在 CPU 瓶颈 3. 之前的 Disk 是 HDD ,现在大部分是 ssd ,导致数据库性能有急剧提升。 综上,以前的观点和现在大家的体感不一致很正常。 |
48
motecshine 2022-10-17 15:01:13 +08:00
我们单表 670GB 数据 OLTP 查询 基本在 20-30ms
|