如何在DuckDB中用Join实现Parquet文件Upsert,避免内存加载大表?
使用Join实现Parquet文件的Upsert操作
核心思路
通过左外连接结合数据合并的方式,无需创建持久化表加载全量数据到内存,直接基于Parquet文件完成Upsert:
- 保留
updates中所有记录(包含需要更新的原有id数据和新增id数据) - 从
main中筛选出未在updates里出现过的id对应的记录(无需更新的原有数据) - 将两部分数据合并,得到最终结果
具体实现(以Spark SQL为例)
直接读取Parquet文件进行操作,无需创建持久化表:
-- 读取两个Parquet文件的数据 WITH main_data AS ( SELECT id, name, city FROM parquet.`/path/to/main.parquet` ), updates_data AS ( SELECT id, name, city FROM parquet.`/path/to/updates.parquet` ) -- 合并更新/新增数据与未被更新的原有数据 SELECT id, name, city FROM updates_data UNION ALL SELECT m.id, m.name, m.city FROM main_data m LEFT JOIN updates_data u ON m.id = u.id WHERE u.id IS NULL;
结果验证
基于示例数据,执行后会得到目标结果:
id name city 1 a m -- 来自updates的更新记录 4 b q -- 来自updates的新增记录 2 b q -- main中未被更新的记录 3 c r -- main中未被更新的记录
优势说明
- 无需将百万级的
main表加载到内存创建持久化表,直接基于文件做Join和过滤,内存占用更低 - 避免了删插操作的性能开销,逻辑简洁易维护
内容的提问来源于stack exchange,提问作者Kumar-Sandeep
相关产品推荐
相关产品推荐

