首页/数据/数仓建模速查/分区策略与模型联动
建模基础69 条

分区策略与模型联动

事实表分区以业务时间为主(按天/月),与查询过滤与生命周期对齐;维度表通常不分区(小表)或按更新时间轻分区。

数仓建模速查数据更新于 2026-10-13

分区策略与模型联动

分区策略与模型联动指分区设计必须与查询过滤习惯、数据生命周期三者对齐。事实表以业务时间为主分区(按天或按月),与报表常见的日期过滤天然匹配;维度表通常是小表,一般不分区,或只按更新时间做轻量分区。分区粒度不是越细越好:数据量不大时按小时分区会制造大量小文件与元数据压力,反而拖慢查询。

基本信息

事实表按业务时间分区(天或月),与查询过滤对齐
维度表一般不分区;大维表可按更新时间轻分区
生命周期保留策略与分区粒度一致,按分区过期清理
粒度选择单分区数据量够大才值得细分到小时
前提查询必须真的带分区键过滤,否则裁剪失效

典型使用场景

  • 报表加速:按业务日期过滤时只扫描对应分区,扫描量下降数量级
  • 数据清理:按分区过期删除历史数据,比按行删除高效且可控
  • 迟到数据回刷:按业务日期分区时只需重写受影响分区
  • 冷热分层:近期分区放高性能存储,历史分区转低成本存储
  • 分区裁剪排查:发现查询变慢时先确认过滤条件是否命中分区键
  • 增量补数:按分区粒度编排重跑范围,避免全表重算

分区设计示例

分区设计示例
-- 事实表:按业务日期分区(Hive 风格)
CREATE TABLE fact_order (
  order_no    string,
  user_sk     bigint,
  pay_amt     decimal(18,2)
)
PARTITIONED BY (dt string);   -- dt 为业务日期,不是入库时间

-- 查询必须带分区过滤,否则全分区扫描
SELECT sum(pay_amt) FROM fact_order
WHERE dt BETWEEN '2026-10-01' AND '2026-10-11';

-- 分区生命周期:保留最近 24 个月,历史分区按批下线
-- ALTER TABLE fact_order DROP PARTITION (dt < '2024-10-01');

分区方案对照

方案适用代价
按业务日期分区绝大多数交易与日志事实表需保证迟到数据能回写历史分区
按入库时间分区只关心到达时间的场景业务时间过滤无法裁剪
按天分区日增量数据量大小数据量时小文件多
按月分区月增量适中、查询按月按日过滤仍要扫整月
按小时分区单小时数据量很大(如日志)小文件与元数据压力显著
分区键的选择本质是「谁的过滤条件最常用」:绝大多数分析都按业务日期看,所以按业务日期分区;如果按入库时间分区,业务日期过滤就无法裁剪,等于白分区。分区粒度则取决于单分区数据量,通常单分区几十 MB 到几 GB 是舒适区间。

易错点

  • 按入库时间分区但查询按业务时间过滤:分区裁剪完全失效,扫描量与全表无异
  • 告警与脚本忽略分区键过滤:单次查询拖满整个集群资源
  • 分区粒度太细(小时):小文件与元数据压力让查询比不分区更慢
  • 保留策略与分区不一致:按行删除历史数据,既慢又容易残留
  • 迟到数据无法回写历史分区:分区只允许追加时,补数只能重建整段区间

数据来源与参考

  • 数据仓库物理设计实践:分区
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌