分库分表是应对单库单表性能瓶颈的务实选择,核心在于拆分问题与分散压力;需依据数据量、连接数、IO、CPU等指标及时介入,优先垂直拆分再水平拆分,并妥善解决跨片查询、分布式事务及运维复杂度问题。

分库分表不是为了“炫技”,而是当单库单表扛不住数据量和并发时,必须做的务实选择。核心就两点:一是把大问题拆成小问题,二是让资源压力分散到多个物理节点上。
先看什么情况下该拆
别等系统卡死再动手。几个明确信号值得警惕:
- 单表行数持续超过 1000万,即使有索引,B+树层级变深,查询明显变慢
- 数据库活跃连接频繁接近上限,报 “Too many connections”
- 磁盘IO高企、缓存命中率骤降,慢查询日志里大量全表扫描或非索引字段过滤
- CPU长期高于80%,且集中在排序、JOIN、聚合类SQL上
垂直拆分:按“业务”或“字段热度”切
适合早期优化,改动小、见效快,是分库分表的第一步。
- 垂直分库:把用户、订单、商品等模块,各自独立成库,部署在不同服务器上。比如 user_db、order_db、product_db —— 解耦业务,隔离故障,也方便按需扩容
- 垂直分表:一张表字段太多(比如50+列),就把高频访问的字段(id、name、status)留在主表;把大字段(description、content、image_urls)或低频字段挪到扩展表。这样查列表页更快,缓存更有效,还能减少锁竞争
- 注意:分表后关联数据不要依赖数据库 JOIN,应在应用层用主键分别查两表再组装
水平拆分:按“数据行”均匀打散
真正解决海量数据和高并发的核心手段,但复杂度更高,务必选好分片键。
- 分片规则要稳定、可预测、分布均匀:常用 user_id % N(哈希)、created_at 按月分表(RANGE)、或按地域/租户ID划分
- 优先分库再分表:比如先按 user_id % 4 拆4个库,每个库里再按 user_id % 4 拆4张表,共16个分片 —— 这样既分散IO压力,又避免单库连接瓶颈
- 字典表要全局可用:状态码、类型名这类高频小表,建议不拆或复制到每个库,避免跨库查询
拆完之后绕不开的现实问题
没有银弹。每种拆法都带来新挑战,得提前想清楚应对方案:
- 跨分片查询难:比如要查“某地区最近7天所有订单”,就得在应用层合并多个库/表的结果,或引入ES做宽表检索
- 分布式事务麻烦:尽量规避跨库更新,用最终一致性(如发MQ消息+本地事务表)代替强一致
- 运维成本上升:建表、备份、扩容、监控都要批量操作,推荐用 ShardingSphere 或自研路由中间件统一管理
- 分片键选错会雪上加霜:比如用时间戳做哈希分片,会导致新数据全部挤在少数分片上,热点集中
基本上就这些。先垂直再水平,先评估再动手,先试跑再上线。拆得合理,系统能撑住十倍增长;拆得随意,可能比不拆还难维护。










