如何在ADF管道中实现SQL源与Sink的记录删除同步?
ADF中处理SQL源/目标数据同步的删除一致性问题解决方案
针对你用Copy Data Activity的Upsert无法处理删除、导致源目标数据不一致的问题,以下几个方案比全量截断+存储过程更高效,也无需大量创建Data Flow:
方案1:临时表+SQL MERGE语句(通用最优)
不用截断目标表,通过临时表中转数据,用MERGE一次性处理增、改、删:
- 同步源数据到临时表:用Copy Data Activity将源表数据同步到目标库的临时表(比如
#SyncTemp),在Pre-copy script中添加TRUNCATE TABLE #SyncTemp确保每次运行清空临时表。 - 执行MERGE语句:添加Execute SQL Activity,运行MERGE逻辑:
MERGE INTO TargetTable AS T USING #SyncTemp AS S ON T.CustomerId = S.CustomerId -- 替换为你的主键 WHEN MATCHED THEN UPDATE SET T.Column1 = S.Column1, T.Column2 = S.Column2 -- 替换为需要同步的字段 WHEN NOT MATCHED BY TARGET THEN INSERT (CustomerId, Column1, Column2) VALUES (S.CustomerId, S.Column1, S.Column2) WHEN NOT MATCHED BY SOURCE THEN DELETE; - 复用逻辑:多个表只需修改MERGE语句中的表名、主键和字段,无需重复创建复杂组件。
- 优点:避免全量截断的锁表风险,性能优于全量覆盖;无需Data Flow,配置成本低。
- 缺点:超大表(千万级以上)需考虑分批次同步临时表,避免MERGE性能瓶颈。
方案2:利用SQL CDC捕获删除操作(高性能增量场景)
如果源SQL Server/支持CDC的数据库(如Azure SQL DB),可以通过CDC捕获删除变更,单独处理:
- 开启源表CDC:在源库启用数据库和目标表的CDC,配置捕获作业记录所有变更(包括Delete)。
- 同步CDC变更数据:用Copy Data Activity读取CDC的变更日志表(如
cdc.SourceTable_CT),筛选出操作类型为D(删除)的记录。 - 批量删除目标表记录:将CDC中删除的主键传入Execute SQL Activity,执行批量删除:
(可通过ADF的参数化或批量拼接实现)DELETE FROM TargetTable WHERE CustomerId IN (@DeletedIds)
- 优点:仅处理增量变更,性能最优;结合Upsert处理增改,CDC处理删除,完美匹配业务场景。
- 缺点:需要源库支持CDC,且需权限配置CDC作业;仅适用于增量同步场景。
方案3:Lookup活动+批量删除(中小表快速方案)
针对数据量较小的表,用ADF原生活动对比主键实现删除:
- 获取源表所有主键:添加Lookup Activity,执行
SELECT CustomerId FROM SourceTable获取源表所有有效主键。 - 批量删除冗余记录:将Lookup结果的主键导入目标库临时表,执行删除:
(若主键数量过多,建议用临时表关联而非IN子句,避免SQL语法长度限制)DELETE FROM TargetTable WHERE CustomerId NOT IN (SELECT CustomerId FROM #SourceKeysTemp)
- 优点:无需额外配置,纯ADF原生活动实现;适合中小表快速落地。
- 缺点:全量读取主键对大表性能影响较大,仅适用于数据量较小的场景。
方案对比与选择
- 若有大量表需同步,优先选方案1:配置复用性高,无需依赖额外数据库功能。
- 若源库支持CDC且以增量同步为主,优先选方案2:性能最优,长期维护成本低。
- 中小表快速解决问题,选方案3:配置最简单,无需复杂逻辑。
Data Flow虽然能实现删除逻辑,但每个表需单独创建数据流,对大量表来说配置成本过高,上述方案更适合你的场景。
内容的提问来源于stack exchange,提问作者AntonyJ
相关产品推荐
相关产品推荐

