全量抽取与增量抽取是什么
全量抽取每次把整张表拉一遍,逻辑最简单,天然覆盖新增、修改与物理删除;增量抽取只取上次之后发生变化的数据,成本低但完全依赖变更标识是否可靠。选择哪一种,取决于源表规模、源库压力预算与业务对删除的敏感度。
为什么常见做法是混合
纯全量在小表上没问题,表一上千万行就会把抽取窗口和源库 IO 一起拖垮;纯增量又看不见物理删除,也无法感知历史数据被人为补录修改。因此常见组合是「首次全量 + 每日增量 + 周期性全量对账」,用增量保时效,用全量兜正确性。
基本信息
| 全量 | 每次抽整表,天然覆盖删除与历史修正 |
|---|---|
| 增量 | 只抽变化行,依赖更新时间列、自增 ID 或 CDC |
| 混合 | 首次全量 + 每日增量 + 周期性全量校验 |
| 水位保存 | 控制表、调度变量或参数文件,不能放脚本本地 |
| 删除捕获 | 增量无法感知物理删除,需 CDC 或全量比对 |
两种方式对比
| 维度 | 全量 | 增量 |
|---|---|---|
| 源库压力 | 每次全表扫描,随表增长变大 | 只扫变化行,相对稳定 |
| 删除感知 | 能,整表覆盖自然同步 | 不能,需 CDC 或全量比对 |
| 实现复杂度 | 低,一条 SELECT 覆盖写入 | 中高,要维护水位与边界 |
| 失败重跑 | 重跑一次即可,代价是全表 | 按窗口重跑,代价小 |
| 适用表 | 维表、小表、配置表 | 订单、流水等大表 |
典型使用场景
- 用户维表、渠道配置等小表:直接全量覆盖,省掉水位维护的复杂度
- 订单、支付流水等大表:必须走增量,否则夜间窗口跑不完
- 合规要求能追溯历史快照:按日保留全量快照分区
- 增量侧看不见删除的场景:周期性用全量比对补齐 delete
- 源端时间戳不可靠(被批量重写):缩短全量周期作为兜底
全量覆盖写入
全量覆盖写入
-- 每天重刷当日快照,维表最常用
INSERT OVERWRITE TABLE dim_user
SELECT user_id, user_name, channel_code, status, update_time
FROM ods_user_full WHERE dt = '2026-10-11'; -- 只覆盖当天分区,历史分区不动增量合并写入
增量合并写入
-- 以主键合并增量,实现 upsert 语义
MERGE INTO dwd_order t
USING ods_order_delta s ON t.order_id = s.order_id
WHEN MATCHED THEN UPDATE SET t.amount = s.amount, t.updated_at = s.updated_at
WHEN NOT MATCHED THEN INSERT (order_id, amount, updated_at)
VALUES (s.order_id, s.amount, s.updated_at);增量抽取的可靠性取决于变更标识:业务批量刷 updated_at 做数据修复时,那一批记录的时间戳会被整体改写,若已超过水位就会漏采,因此要定期全量核对。
增量任务与全量任务的数据口径要对齐:同一张表两条链路写入时,字段类型、空值处理、时间精度必须一致,否则对账会出现无法解释的差异。
水位值不能只存在脚本所在机器的本地文件里:换机器或容器重建就丢失,会从最早或当前位置重新开始,前者造成重复,后者造成漏数。