不少技术文章都直接引用了这个观点,但没说为什么?有大佬解释下这个理论依据吗?

听说 MySQL 单表超过 1000 万行性能会急剧下降。

这应该是个经验数字,不一定绝对对。 但是如果你只有几十 几百万的数据,就大概率是直接用就好,不需要考虑那么多事情

可能和 b 树的深度,和 Page 的大小有关

反正 20 天前,在一个 帖子 里,有很多人反映,MySQL 单表存 1~2 亿(#11 楼 #16 #18 #19 #21 #35 )、4 亿(#27 )、10 亿(#36 )、20 亿(#28 )都没问题,查询也很快(< 10 ms ,#27 #28 )

我在那个帖子里的 3 楼,也问了个类似的问题,也给出一点猜测(但没人理我。。)

  1. 经验数字
  2. 阿里(也许)自己有足够完善的组建处理分库分表
  3. 阿里(也许)可以通过传播这个数字,卖更多的数据库或者其他服务

备份、恢复数据的难度,太大了也是灾难

很多业务,估计一个小时就要分一次表了

才 500 万,哪怕机械硬盘时代都毫无问题,更别提现在的高速 SSD

分库分表没那么好玩,应用端需要精心设计,不能像单库那样随心所欲的写 SQL 。

之前有人说是 2000w 行,查了一下是索引数深度的效率相关

可以加一个 db proxy 层,这一层屏蔽分表分库细节,你代码里面依然可以当单表使用,随心所欲的写 sql 。

那是说的机械硬盘经验值, 还是偏保守的那种.
现在的 M.2 SSD, 三星 980PRO, 随机 4k 读写速度是普通机械的 500 倍往上, 同样的, 500 万*500=25 亿, 也就是说, 保守点估计 25 亿行数据再考虑分库分表, 胆子大一点的, 100-1000 亿行数据以上再去考虑这个问题.

分布式数据库一般都有 DB Proxy 的,但是 SQL 落到多个库,数据量大的时候,Proxy 每个节点都取数据来处理的时候,一是慢,二是容易内存超量,例如有 1024 个节点,要查询 1000 行,不巧写的 SQL 没有分片键,那么就要去这 1024 个节点上各自都获取 1000 行数据,Proxy 得到 1024 * 1000 行数据进行 Merge Sort ,然后再判断一次取出合适的 1000 行。

最直观的是使用 Sharding Sphere ,或者看看 TDSql 等的设计文档,没那么自由。

一张 table 2GB 就性能下降到不可接受了,怕是在用十年前的 DB 吧

mp.weixin.qq.com/s/XX_NkIIf_PLyU4IE6lEEYQ

老民科八股文了,遗毒万年
生产环境近两亿行的主表,0.2ms 查询时间,分库分表?分个 J2

我怀疑写八股文和背八股文的人不懂什么是 O(log(n)),就硬背树深了一层

健康项目中:低效率查询,未命中索引的查询应该在 Code Review 阶段被驳回的。过早期的分库分表还会极大提高总持有成本,百害而无一利。因为只需要简单的主从读写分离架构就可以支撑到数万 TPS 了。

这应该是个经验之谈。主要是看表怎么用,如果仅仅是主键查询 10 亿都不要分表。

什么数据库,什么版本,硬件性能咋样,如果是 mysql 用的是什么引擎,条件不充分都是空谈。我觉得测试之后才能有结果,真正实践的话也要对数据库进行测试。

物理定律还有适用条件呢,更何况数据库的访问模式不同,硬件、软件也会不断地迭代和优化

分表并不会让事情变得更简单,仅仅是用逻辑复杂度代替空间复杂度而已

是不是民科不重要,重要的在于程序员的素养,如果考虑到外包团队普遍拉垮的质量,以及 java mysql 这些在企业应用中的高占比,我赞同 500w 分表

应该没这么夸张。
自建的文件元数据索引表没能正确处理符号链接 loop ,结果整出来几百 G 的表,直到手工执行 count(*)的时候才发现不对劲,其它操作基本无感

应该是性能目标不一致造成的错觉

[查询没有问题] 这个本身就很主观的东西,不同企业不同场景对 [查询没问题] 的定义可以差很大的啊

其他企业敢说自己的查询目标要求与阿里场景和要求一致吗?

阿里的技术手册,其他实体应当仅供参考。

之前生产环境有张过亿的表,其实表大了 查询还好,插入更新的时候,cpu 磁盘都会飙升,而且索引建的不科学的话,大表真的是噩梦,大表再数据插入的时候,还不稳定,时间慢,所以我感觉查询并不是分库分表的原因
这种情况在数据千万级别的时候就慢慢开始显现,但是这个 500W 的数字我也不知道怎么得出的

过亿有索引的查询肯定没问题。

有没有人试过修改、更新、和连表的性能?

insert 跟 update 的时候会有问题 如果 update 的范围过大 可能该表就卡住了一样 而且时间还不稳定 尤其是索引多一点的时候 简直是噩梦

查单条肯定随便过亿,其他操作我擦我不好说

实际工作中遇到过表数据超过两千万的情况,没有分表,是公司内 IM 的聊天记录。
结论是:查询、插入,以及主键更新,甚至索引做的不错,条件查询、翻页也还可以。
但是:开发新功能时,表结构变更,一个不注意,就是灾难。变更一次锁表 20 分钟。

表设计的垃圾才需要

这当然是经验只谈.

几百万的表, 单表查基本没事.

越大单表风险越大, 还是趁早拆.

它就是随便一说,不要这样机械,一旦启用分表,你的程序也要对应的修改,分表的好处是:系统具备横向扩容的能力. 流量大幅度上涨之后,加点机器就能抗住,如果没有这个需求就不需要扩

只要硬盘够大,单表存放数量随便

小马过河,自己趟一趟才知道深浅。索引做得如何、SQL 复杂度、硬件配置、每行数据的数据量都会对结果有影响。有十几亿记录数的表也跑得欢,也遇到过百万的表就已经很慢。

分表分库这些都是有代价的,分了以后业务开发难度会明显增大,越复杂的业务越是如此。
很多公司负责技术架构的人并不参与业务开发,说得不好听,为了自己的 KPI ,纸上谈兵拍脑袋定方案,害人不浅。

分不分表,怎么分,都要看具体业务和原有设计。

超过 500 万行或 2GB 才推荐,也就是说不超过 500 万行或 2GB ,不推荐分表,因为完全没有这个必要。

我们公司以前是 800w 行,但实际生产上也有超过 4000w 行的表跑着

甚至没提硬件。。就嗯背八股

我记得 oracle 是 1 亿,mysql 不至于这么拉胯吧?

12 年的时候,mysql 免费版 大概 600 多万 数据是个分界线

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 的浪费,因为每次至少读一页)。

非常赞

之前一个人能搞定, 分表后需要一个团队维护. 对部门有利.

我们存了十几亿数据,看你怎么查,不是所有查询都会很慢

阿里人家数据库实例是什么规格都没给你说, 你怎么确定自己的实例规格要按照 500w 或 2GB 来呢, 阿里的技术手册, 就看看就行吧. 经验值始终要去躺一次才知道什么效果, 没必要强硬生套.

  1. 十年前的 mysql 的确不太行( 5.7 之前)
  2. 十年前的 CPU 性能瓶颈也很大,不分库存在 CPU 瓶颈
  3. 之前的 Disk 是 HDD ,现在大部分是 ssd ,导致数据库性能有急剧提升。
    综上,以前的观点和现在大家的体感不一致很正常。

我们单表 670GB 数据 OLTP 查询 基本在 20-30ms