首页/数据/数据工程与 ETL 速查/全量抽取与增量抽取
管道基础52 条

全量抽取与增量抽取

全量每次覆盖整表、逻辑简单但源端压力大;增量只取变化数据、成本低但依赖可靠的变更标识。常见组合是首次全量、后续增量、定期全量对账。

全量抽取与增量抽取是什么

全量抽取每次把整张表拉一遍,逻辑最简单,天然覆盖新增、修改与物理删除;增量抽取只取上次之后发生变化的数据,成本低但完全依赖变更标识是否可靠。选择哪一种,取决于源表规模、源库压力预算与业务对删除的敏感度。

为什么常见做法是混合

纯全量在小表上没问题,表一上千万行就会把抽取窗口和源库 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 做数据修复时,那一批记录的时间戳会被整体改写,若已超过水位就会漏采,因此要定期全量核对。
增量任务与全量任务的数据口径要对齐:同一张表两条链路写入时,字段类型、空值处理、时间精度必须一致,否则对账会出现无法解释的差异。
水位值不能只存在脚本所在机器的本地文件里:换机器或容器重建就丢失,会从最早或当前位置重新开始,前者造成重复,后者造成漏数。

易错点

  • 源表 updated_at 被业务批量重写(例如数据修复跑批)时会漏掉这批历史修正,必须定期全量核对并补刷受影响分区
  • 增量任务把水位保存在脚本本地文件,换机器即丢失,应放在控制表或调度平台变量里并纳入版本管理
  • 全量覆盖时忘了限定分区,一次作业清空整表历史,属于典型的高危误操作
  • 增量链路只做 insert 不做 update 分支,主键冲突时报错或静默丢弃,最终表现为业务数据长期不更新

数据来源与参考

  • Kimball《The Data Warehouse Toolkit》ETL 子系统:增量抽取
  • Apache Hive LanguageManual DML
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌