按天分区是什么
按天分区是数仓最常用的粒度:把 dt 作为分区字段,每天对应一个数据目录,查询时带 dt 条件即可裁剪掉无关数据,这是全表扫描与分区扫描的分水岭。设计要点有四个:分区值用 yyyy-MM-dd 这类规范格式、每个分区的数据量控制在可接受范围、查询必须带分区条件、分区总数与文件总数要评估元数据压力。
基本信息
| 粒度 | 天,按业务日期或数据日期 |
|---|---|
| 分区值格式 | yyyy-MM-dd,不带时分秒 |
| 查询要求 | WHERE 必须带 dt 条件 |
| 压力来源 | 分区总数与每个分区的文件数 |
| 常见变体 | 小时分区、月分区、多级分区(如 dt + 城市) |
典型使用场景
- 绝大多数离线明细表:按天落分区,也按天重跑与回刷
- 需要回溯历史:某天数据出错只重算该分区,不影响其他日期
- 控制查询成本:带 dt 条件后只扫当天分区,扫描量可预估
- 生命周期管理:按分区批量归档或删除过期数据
- 多引擎共用:分区目录结构统一,Spark、Trino 都能直接裁剪
设计要点
| 要点 | 做法 | 不做的后果 |
|---|---|---|
| 分区值格式 | 统一 yyyy-MM-dd,不带时分秒 | 格式混用会让裁剪失效或产生重复分区 |
| 分区粒度 | 按数据量与查询习惯选天、小时或月 | 粒度过细产生大量小文件与元数据压力 |
| 每分区数据量 | 控制单分区文件数与单文件大小 | 小文件过多拖慢作业启动与扫描 |
| 查询约束 | 所有查询必须带分区条件 | 不带分区等于全表扫描,严重时拖垮集群 |
日分区表
日分区表
CREATE TABLE dwd_trade_order_di (
order_id STRING, -- 业务主键
pay_amt DECIMAL(18,2) -- 金额统一精度
)
PARTITIONED BY (dt STRING) -- 分区字段:数据日期
STORED AS ORC; -- 列式存储,扫描更快
-- 查询带上分区条件才能触发分区裁剪
SELECT count(1) FROM dwd_trade_order_di WHERE dt='2026-10-13';十年日分区约 3650 个,配合文件数治理后元数据压力可控;数量再高时可以按业务域拆表,或对历史数据改用月分区。真正决定查询规划快慢的,是元数据里的分区数与文件数,而不是分区这个设计本身。