首页/数据/数仓建模速查/ReplacingMergeTree 去重与 FINAL
湖仓与引擎63 条

ReplacingMergeTree 去重与 FINAL

ReplacingMergeTree 后台合并时按排序键去重保留版本号较大的那一行;查询加 FINAL 可强制去重,但会牺牲并行度与性能。

数仓建模速查数据更新于 2026-10-13

ReplacingMergeTree 去重与 FINAL

ReplacingMergeTree 在后台合并(merge)时按排序键去重,保留版本列取值较大的那一行;去重发生在合并阶段而不是写入阶段,所以合并完成前同一个键可能有多行可见。查询加 FINAL 可以强制返回去重后的最新行,代价是牺牲并行度、随数据量上升明显变慢。

基本信息

引擎ReplacingMergeTree
去重键ORDER BY 指定的列
版本列可选,决定保留哪一行
FINAL查询期强制去重
合并时机后台异步,时间不可控

典型使用场景

  • 维表按主键保留最新版本:门店、商品属性变更只需写入新版本行
  • 明细去重:同一订单重复投递时按排序键加版本列收敛为一条
  • 总量类统计:不依赖 FINAL,或按版本过滤后再聚合,避免查询期开销
  • 高并发明细查询:改为查询前先去重,或直接使用已去重的聚合表
  • 调优排查:确认 OPTIMIZE 是否在运行、单分区是否过大导致合并追不上写入速度

按版本取最新

按版本取最新
-- 不依赖 FINAL 的等价写法:按排序键取版本最大的一行
SELECT store_id, store_name
FROM (
  SELECT store_id, store_name,
         row_number() OVER (PARTITION BY store_id ORDER BY version DESC) AS rn
  FROM dw.dim_store
)
WHERE rn = 1;
-- 主动触发合并(大表开销高,宜按分区执行)
OPTIMIZE TABLE dw.dim_store FINAL;

去重手段对比

手段代价适用
依赖后台合并自动但时机不可控最终一致可接受的统计场景
查询加 FINAL查询开销随数据量上升小表或偶发的精确查询
按版本取最新需要排序聚合明细类精确查询
入仓前去重写入端多一步处理高频读取的维表
ReplacingMergeTree 的语义是最终一致:合并时间不由使用者决定,因此对准确性要求高的查询不能只依赖后台合并,应显式去重。
较新版本的 ReplacingMergeTree 支持额外的删除标记参数(is_deleted),可用于逻辑删除;升级或跨集群迁移前先核对目标版本的参数支持情况,避免建表语句不兼容。

易错点

  • 依赖 FINAL 实现去重:查询开销随数据量上升,大表上容易直接超时
  • 认为写入即去重:合并前同键多行可见,精确计数与金额汇总会被重复计算
  • 排序键设计不含业务主键:同一主键落在不同分区,永远不会被合并到一起去重
  • 无节制对大表执行 OPTIMIZE 加 FINAL:合并占用大量 IO,影响在线查询响应

数据来源与参考

  • ClickHouse 官方文档:ReplacingMergeTree
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌