分库分表是高并发写入超限后的硬需求,需权衡时机、分片键选择、全局ID生成、中间件选型及聚合查询优化,核心在于业务能否接受最终一致性与分布式妥协。
当 INSERT 和 UPDATE 请求持续超过每秒几千次,且主库 CPU 常年 >80%、慢查询陡增、主从延迟飙升到分钟级,说明单实例的写能力已触顶。MySQL 单表超过 5000 万行后,即使有索引,ALTER TABLE 可能锁表数小时,DELETE 旧数据也容易拖垮复制线程。这不是“要不要做”,而是“再不做线上就要抖动甚至挂掉”。
过早分库分表会引入路由复杂度、跨库事务难保证、JOIN 和 GROUP BY 变得低效甚至不可用。常见误判点:只看数据量,不看访问模式。比如日志类表虽有百亿行,但基本只按时间范围 SELECT,用分区表(PARTITION BY RANGE)就够了;而用户订单表既有高频按 user_id 查询,又有按 order_no 查单条,这才真正需要分库分表。
create_time 分片,所有新订单都打到最新分片,其他分片闲置SNOWFLAKE、UUID 或号段模式生*局唯一 id
如果你的业务重度依赖 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(*) 不再是 O(1),而是要扫所有分片再合并;ORDER BY create 会被改写成每个分片取 100 条,再内存排序取前 100——实际扫描行数可能是原来的 N 倍(N=分片数)。这类查询响应时间会随分片数线性恶化。
last_create_time 做游标分页,避免 LIMIT 10000, 20
分库分表真正的门槛不在技术实现,而在业务逻辑是否愿意为分布式妥协——比如放弃跨用户汇总报表,或接受“最近 7 天订单数”有 2 秒延迟。这些决策比选哪个中间件重要得多。