SQL 水平分表是将大表按行拆分为结构相同的小表以降低单表数据量,缓解性能问题;主要策略包括 ID 范围分表(适合自增 ID、易归档但易热点)、时间分表(适配时序数据、冷热分离好但跨期查询复杂)和哈希分表(负载均衡好但不支持非分片键范围查询),落地需解决路由统一、全局 ID、跨表聚合及扩容等关键问题。

SQL 水平分表的核心,是把一张大表按行拆成多个结构相同的小表,让单表数据量降下来,从而缓解查询慢、锁竞争、索引深度过大等问题。它不改变字段结构,只分散数据行,适合单表超千万甚至亿级的场景。
按 ID 范围分表:适合有明显顺序特征的数据
比如订单表主键是自增 ID,可按 ID 段切分:order_0001(1–100 万)、order_0002(100 万零 1–200 万)……这种策略逻辑简单,归档和删除历史数据方便,比如直接 DROP 掉 order_2022 的整张表。
- 适用场景:ID 连续增长、业务写入相对均匀、查询常带 ID 区间条件(如“查 ID 在 50 万到 80 万之间的订单”)
- 注意点:容易产生热点——新订单总往最新表写,导致该表 QPS 高、磁盘 IO 集中;老表长期闲置,资源利用不均
- 建议搭配时间维度使用,例如“ID % 100 + 年份”组合,缓解单一维度倾斜
按时间分表:天然适配时序类业务
电商订单、日志、监控数据等,天然按天 / 月 / 年归档。可建表 order_202601、order_202602……查询某个月数据时,路由明确,无需扫描全量表。
- 优点:冷热分离清晰,历史表可设为只读或迁至低配存储;备份恢复粒度更细
- 缺点:跨月份查询(如“近 90 天订单汇总”)需应用层合并结果;月末 / 年初可能因批量导入造成单表瞬时压力
- 小技巧:用分区表(PARTITION BY RANGE (TO_DAYS(create_time)))替代手动建表,运维更轻量,但本质仍是逻辑分表
哈希分表:追求数据与负载均衡
对分片键(如 user_id、order_no)做哈希再取模,决定写入哪张子表。例如 user_id % 16 → 写入 order_0000 到 order_0015 中的某一张。
- 优势:数据分布较均匀,读写压力天然打散,不易出现单表瓶颈
- 限制:无法支持非分片键的范围查询(如“查所有上海用户”若没存 city 字段在分片键里就难路由);扩容时模数变化需迁移大量数据
- 进阶做法:用一致性哈希减少扩容迁移量,或结合虚拟节点提升均匀性
设计时必须考虑的关键细节
分表不是建几张新表就完事,真正落地要闭环处理几个硬性问题:
- 路由逻辑必须统一且稳定 :应用层或中间件(如 ShardingSphere)需根据分片键准确算出目标表名,不能靠人工拼接或配置错位
- 全局唯一 ID 不能依赖自增主键 :每张子表独立自增会导致 ID 冲突,得用雪花算法、数据库号段、或 UUID+ 时间戳组合生成
- 跨表聚合和 JOIN 基本不可行 :MySQL 原生不支持跨表关联,统计类需求需在应用层收拢多表结果,或引入 ES、OLAP 引擎辅助
- 务必预留扩容路径 :比如初始 16 张表,未来要扩到 64 张,提前设计好 ID 哈希空间,避免全量重分






























