为什么即使合并不更新任何内容,Databricks Delta 也会复制未修改的行?

Why Databricks Delta is copying unmodified rows even when merge doesn't update anything?

当我 运行 查询时:

merge into test_records t
using (
select id, "senior developer" title, country from test_records where country = 'Brazil'
) u
on t.id = u.id
when matched and (t.id <> u.id) then -- this is just to be sure that nothing will get updated
  update set t.title = u.title, t.updated_at = now()
when not matched then 
  insert (id, title, country, created_at, updated_at) values (id, title, country, now(), now());

当我运行描述目标table的历史时,我仍然看到以下数据:

{"numTargetRowsCopied": "2", "numTargetRowsDeleted": "0", "numTargetFilesAdded": "1", "numTargetRowsInserted": "0", "numTargetRowsUpdated": "0", "numOutputRows": "2", "numSourceRows": "2", "numTargetFilesRemoved": "1"}

在火花中 ui 我看到了这个:

所以未修改的行被无故(?)重写。这是为什么?

免责声明:我一直在研究它,我只能告诉你代码的样子,但不能告诉你为什么会这样。


此 no-match-row MERGE INTO 解析为 MergeIntoCommand logical command (that is executed on the driver). You can find all the performance metrics here (with numTargetRowsCopied)。

我们的指标

导致我们writeAllChanges

这段代码的有趣之处在于它选择了 rightOuterfullOuter 的联接类型。为 org.apache.spark.sql.delta.commands.MergeIntoCommand 记录器打开 DEBUG 日志记录级别,以查看打印到日志中的内部消息。

另一个非常有趣的事情是指标是作为 UDF 计算的(!)我们的是 here

最后,these lines 是执行 UDF 和递增指标的地方。评论特别感兴趣:

// Target row did not match any source row, so just copy it to the output

我想这说明了一切。没有匹配项会导致 numTargetRowsCopied 指标递增。我猜你在目标 table 中有两行,是吗?