连载中 1/20

单表两亿行:一次改了八小时的 DDL,逼出了分库分表

2026-07-18 · 2637 阅读 · 0 评论 · 0 赞

一张表的两亿行时刻

故事从一张订单表说起。业务跑了两三年,订单表两亿行,平时查询有索引护体,看起来岁月静好。直到产品要在订单上加一个「渠道来源」字段——DBA 拿着方案皱了半天眉:在线 DDL 工具全量拷表加回放增量,八小时起步;拷表期间磁盘要多占一份空间,主从延迟会全程飘红。最后 DBA 说了一句让人清醒的话:这不是慢,是这张表已经不配再被改了。

单表规模逼近天花板时,问题从来不是一个,是一串:索引膨胀——B+ 树层级涨上去,每个查询多几次磁盘 IO;DDL 慢如老牛——任何结构变更都要全量拷表;备份窗口失控——全量备份跑不完一个夜里;磁盘与内存水位——Buffer Pool 装不下热数据,命中率往下掉。这一串问题互为帮凶,拖到最后就是线上事故。

什么规模才算到顶

先泼冷水:两亿行不等于必须拆。行数只是表象,真正的判断依据是「顶格优化之后还撑不撑得住」。行业里常见的参考线是:单表行数向千万级靠拢、单库数据量向 TB 级靠拢、QPS 向单实例瓶颈(万级上下)靠拢——三条里撞了两条,就该认真评估。但参考线只是提醒,不是判决,很多所谓「必须拆」的场景,把索引建对、把冷数据归档掉、把读流量分出去之后,还能再撑两年。

所以这个系列的第一课是克制:分库分表是高成本的重构,不是性能优化的第一步。它带来的复杂度——跨片查询、分布式事务、数据迁移、运维翻倍——会跟随系统余生。下一篇先把「拆之前还能做的三招」讲透,三招打完还顶不住,再来动刀。

拆库与拆表:两把不同的刀

「分库分表」四个字其实混着两种手术。分表:把一张大表切成多张结构相同的小表,可以只在一个实例里分(table_0 到 table_63),也可以分到多个实例。分表直接解决单表问题——索引层级、DDL 时长、行数规模;但如果这些表还住在同一个实例里,实例级的瓶颈(CPU、内存、磁盘、连接数、QPS 上限)一个都没解决。

分库:把数据拆到多个 MySQL 实例上,每个实例独享 CPU、内存和磁盘,写能力与容量一起线性扩展。分库必然分表(每个实例上就是一张张小表),而分表不一定分库。所以真正的选型问题只有一个:瓶颈在表还是在实例?表大就分表,实例撑不住就分库,多数大系统最后两者都要——「N 库 M 表」的矩阵式拆法就是答案,比如 8 库 64 表,每个库 8 张。

动刀前的全景清单

确定要拆之后,决策链有五环,这个系列按这个顺序展开:怎么切——垂直还是水平,刀口选在哪(第 3-4 篇);键怎么定——分片键是终身选择(第 5 篇);路由怎么落——代码、代理还是 SDK(第 6-8 篇);查询怎么办——跨片聚合、分页、JOIN(第 9-10 篇);数据怎么迁——双写、校验、切流(第 14-15 篇)。每一步都有回头路,唯独分片键没有——它会锁死系统的查询能力很多年。

下一篇,先把刀放下,聊聊拆之前那三招顶格优化——很可能你的两亿行,瘦完身就不需要这一刀了。

☕
503

10 年全栈工程师 · 503咖啡馆主理人

#分库分表#单表上限#分表分库#DDL#容量规划

评论 (0)

热门推荐

连载中 11/22

主从搭建实操:从零配出一主两从

光讲原理不过瘾?手把手搭一主两从:my.cnf 六个参数、复制账号、GTID、CHANGE REPLICATION SOURCE TO、SHOW REPLICA STATUS 验收,附翻车排查清单。

#MySQL#主从复制#GTID#主从搭建#高可用
2026-05-07 · 10101 阅读 · 0 评论 · 0 赞
连载中 16/22

连接池:HikariCP 参数与连接风暴

连接池不是越大越好:8 核机器配 1000 连接反而更慢的数学原理,HikariCP 四个必调参数,maxLifetime 与 wait_timeout 的隐形陷阱。

#MySQL#连接池#HikariCP#maxLifetime#连接风暴
2026-05-10 · 9872 阅读 · 0 评论 · 0 赞
连载中 4/16

缓存穿透:恶意 ID 打穿 MySQL 的四道防线

请求的数据在缓存和数据库里都不存在时,缓存形同虚设。聊聊参数校验、空值缓存、布隆过滤器、限流熔断四道防线的原理与组合打法。

#Redis#缓存穿透#布隆过滤器#高可用
2026-05-16 · 9293 阅读 · 21 评论 · 287 赞