分库分表仅适用于单表超千万行、高QPS、可接受最终一致性且具备分布式运维能力的场景;分片键应优先选高频查询字段如user_id,避免create_time导致热点;在线DDL需用gh-ost等工具规避锁表;分库后须监控慢SQL、数据倾斜及冷热分离。

分库分表不是万能解药,得看场景
大表问题核心是单机资源瓶颈:IO吞吐扛不住、查询响应变慢、DDL锁表时间不可控。分库分表能缓解,但会引入分布式事务、跨库JOIN、全局ID、数据迁移等新复杂度。真正适合的场景是:
- 单表数据量持续超千万行,且写入/查询QPS高
- 业务可接受最终一致性(如订单与物流状态不同步几秒)
- 团队具备中间件运维和分布式问题排查能力
- 原有架构已无法通过索引优化、读写分离、归档冷数据等方式解决
分片策略要对齐业务主键和查询模式
别一上来就按时间分片或随机哈希。优先考虑业务高频查询字段,比如:
- 订单表用 user_id 做分片键:90% 查询带用户维度,路由精准,避免跨库
- 若常按 order_no 查询,且 order_no 含时间戳+序列号,可用前缀哈希或范围分片
- 避免用 create_time 单独分片:易导致热点(如秒杀集中写入同一分片)
- 复合分片慎用:增加路由逻辑复杂度,中间件支持度不一(如ShardingSphere支持,MyCat较弱)
在线DDL必须绕过原生锁,靠工具+灰度
MySQL 5.6+ 虽支持 ALGORITHM=INPLACE,但仍有元数据锁(MDL)和部分场景仍需拷表。安全做法是:
- 小表(pt-online-schema-change 做双检
- 中大表(>100万行):强制走 gh-ost,它基于binlog异步追平,全程无锁,支持暂停/回滚
- 所有DDL上线前,在影子库做全量压测:验证索引是否生效、慢查是否新增、应用SQL执行计划是否突变
- 变更窗口选在低峰期,并配置 --max-load="Threads_running=25" 等阈值自动暂停
分库后运维要补上“看不见”的能力
分片不是切完就结束,日常要盯住这些点:
- 慢SQL必须聚合分析:ShardingSphere Proxy 日志 + 开启 sql.show=true,识别未命中分片键的广播查询
- 定期校验分片数据倾斜:用 SELECT table_schema, table_name, data_length FROM information_schema.tables 对比各分片大小,偏差超30%就要重平衡
- 冷热分离自动化:把 create_time 的历史订单归档到独立归档库,应用层路由规则同步更新
- 全局唯一ID不能只靠数据库自增:统一用雪花算法(Snowflake)或数据库号段模式,避免分片间主键冲突










