Databricks MERGE INTO插入时源视图数据被删的原因及规避咨询
问题
执行以下Databricks Upsert语句时,每次触发插入操作,my_source_table中的数据都会被删除:
MERGE INTO my_target_table AS target USING (SELECT MAX(__my_timestamp) AS checkpoint FROM my_source_table) AS source ON target.name = 'some_name' AND target.address = 'some_address' WHEN MATCHED AND source.checkpoint IS NOT NULL THEN UPDATE SET checkpoint = source.checkpoint WHEN NOT MATCHED THEN INSERT (name, address, checkpoint) VALUES ('some_name', 'some_address', source.checkpoint)
编辑补充:此前my_source_table为视图,改为表后该问题消失。
原因分析
核心问题出在**my_source_table是视图而非物理表**:
- 如果这个视图基于临时表、流表或带有消费逻辑的数据源(比如Kafka流自动提交偏移量)创建,执行
SELECT MAX(__my_timestamp)查询视图时,会触发底层数据源的消费或清理逻辑——比如流视图读取完数据后自动清空临时存储,或是视图定义中隐含了数据删除操作。 - MERGE语句执行时会完整计算USING子句的查询,一旦视图关联了修改源数据的逻辑,就会导致源数据被误删。
解决方案
在不改变原有业务逻辑(取源表最大时间戳作为checkpoint)的前提下,可采用以下方式:
- 替换为物理表:这是已验证有效的方案,物理表持久化存储数据,查询时不会触发数据删除逻辑,完全保留原有业务逻辑。
- 调整视图定义(若必须用视图):
- 若视图基于流数据源,确保流读取模式为
append,避免complete或trigger once模式下的自动清理; - 移除视图定义中任何修改、删除源数据的语句(比如带DELETE的CTAS语句);
- 给视图添加缓存:
CACHE VIEW my_source_table,减少重复查询对底层数据源的影响,同时注意配置缓存刷新策略。
- 若视图基于流数据源,确保流读取模式为
内容的提问来源于stack exchange,提问作者Gilo
相关产品推荐
相关产品推荐

