分库分表是高并发写入超限后的硬需求,需权衡时机、分片键选择、全局ID生成、中间件选型及聚合查询优化,核心在于业务能否接受最终一致性与分布式妥协。

单库单表撑不住高并发写入时,分库分表是硬需求
当 INSERT 和 UPDATE 请求持续超过每秒几千次,且主库 CPU 常年 >80%、慢查询陡增、主从延迟飙升到分钟级,说明单实例的写能力已触顶。MySQL 单表超过 5000 万行后,即使有索引,ALTER TABLE 可能锁表数小时,DELETE 旧数据也容易拖垮复制线程。这不是“要不要做”,而是“再不做线上就要抖动甚至挂掉”。
分库分表不是越早越好,但拖到主键自增溢出就晚了
过早分库分表会引入路由复杂度、跨库事务难保证、JOIN 和 GROUP BY 变得低效甚至不可用。常见误判点:只看数据量,不看访问模式。比如日志类表虽有百亿行,但基本只按时间范围 SELECT,用分区表(PARTITION BY RANGE)就够了;而用户订单表既有高频按 user_id 查询,又有按 order_no 查单条,这才真正需要分库分表。
- 分库前必须确认业务能否接受最终一致性——分布式事务(如 Seata)代价远高于应用层补偿
- 分表键选错会导致热点,比如用
create_time分片,所有新订单都打到最新分片,其他分片闲置 - 自增主键在分库后失效,必须改用
SNOWFLAKE、UUID或号段模式生成全局唯一id
ShardingSphere 和 MyCat 的核心差异在 SQL 兼容性上
如果你的业务重度依赖 SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id,优先选 ShardingSphere-JDBC:它在 JDBC 层解析 SQL,支持部分跨库 JOIN 和子查询;而 MyCat 是代理层,对复杂嵌套查询支持弱,且一旦配置错误,可能直接返回空结果而非报错。
-
ShardingSphere要求明确声明分片规则,比如t_order按user_id % 4分 4 库,t_order_item必须用相同算法,否则关联查不出数据 -
MyCat的scheme.xml里写错一个dataNode名称,连接不报错但所有写入静默失败——务必用show databases;和show tables;验证路由是否生效 - 两者都不支持
SELECT ... FOR UPDATE跨库加锁,涉及资金扣减等强一致性场景,得退回到单库或改用 TCC 模式
分库后 COUNT(*)、ORDER BY LIMIT 100 这类聚合操作最易翻车
分库分表后,COUNT(*) 不再是 O(1),而是要扫所有分片再合并;ORDER BY create_time DESC LIMIT 100 会被改写成每个分片取 100 条,再内存排序取前 100——实际扫描行数可能是原来的 N 倍(N=分片数)。这类查询响应时间会随分片数线性恶化。
- 统计类需求尽量走离线数仓(如 Doris / StarRocks),别压在交易库上
- 分页深度超过 1000 时,强制要求前端传
last_create_time做游标分页,避免LIMIT 10000, 20 - 如果必须实时 COUNT,可在写入时用 Redis HyperLogLog 做近似去重,误差率可控在 0.81%
分库分表真正的门槛不在技术实现,而在业务逻辑是否愿意为分布式妥协——比如放弃跨用户汇总报表,或接受“最近 7 天订单数”有 2 秒延迟。这些决策比选哪个中间件重要得多。










