先问三个问题
上一篇那张两亿行的订单表,团队的第一反应是「上分库分表」,被我按住了。动刀之前先回答三个问题:索引建对了吗?冷数据归档了吗?读流量分出去了吗?三个问题对应三招顶格优化,成本低一个数量级,见效却常常立竿见影。很多「必须拆表」的项目,三招打完发现单库还能再战两年。
第一招:归档冷数据
互联网业务的数据有铁律:绝大多数查询只发生在最近的数据上。订单查询的九成以上落在近三个月,两年前的订单一年也翻不了几次。把这张两亿行表按时间拉个直方图,你会发现真正被频繁访问的只有两三千万行——剩下那一亿七八,全是压在索引里、拖慢每一层 B+ 树的死重。归档的刀法:建一张结构相同的归档表(或直接进归档库),写个分批任务把超过阈值的数据搬过去,主表瞬间瘦身。收益立竿见影:索引层级变矮、Buffer Pool 命中率上升、DDL 时长跟着行数一起缩。归档任务的三个纪律——限速(别把主库 IO 打满)、幂等(可重跑)、可回捞(偶尔要查旧订单,得有去处)——第 17 篇展开。
第二招:读写分离加缓存
单实例的瓶颈分读写两侧,而多数业务读远大于写。主从加路由的读写分离架构,能把读流量分给多个从库,写主库单独喘气;热点的读再往前顶一层缓存,Redis 扛走大头,DB 只接未命中的流量。这一招解决的是「实例的 QPS 瓶颈」——但它有个诚实的边界:写 QPS 分不出去。主库只有一台,写入能力就只有一台的上限。如果顶不住的是写、且单表行数同时告急,三招就只剩最后一根稻草。
第三招:索引与 SQL 治理
很多「表太大了」的体感,其实是「SQL 太烂了」的错觉。MySQL 系列里演练过的那套武器——慢查询日志、EXPLAIN、索引设计——在这里全部适用,而且大表上收益被行数放大:小表上全表扫描慢 50 毫秒,两亿行的表上就是 50 秒。治理的产出要沉淀成规矩:慢 SQL 台账、索引评审、深分页禁令。没有这套地基,拆完库该慢还是慢——分库分表会把烂 SQL 从「一张大表的慢」变成「三十二张小表的慢乘以归并」,只会更糟。
三招之后,才是动刀
三招的分工画一张图:归档治行数,读写分离加缓存治读 QPS,SQL 治理治慢的根源。三招打完还剩两类无解的病:写 QPS 超过单实例上限,以及热数据本身的行数规模(归档后主表还有几千万上亿且持续增长)——这才是分库分表的入场券。记住这个顺序:优化是手段,拆分也是手段,先便宜的、后昂贵的。
确认动刀之后,第一个问题是方向:刀往哪里落?垂直还是水平?下一篇从两种拆法的本质差异讲起。
评论 (0)