ReplacingMergeTree 表引擎
该引擎与 MergeTree 的不同之处在于,它会移除具有相同 排序键 值的重复条目(ORDER BY 表段,而不是 PRIMARY KEY)。
数据去重仅在合并期间发生。合并在后台以未知时间进行,因此无法计划。部分数据可能未被处理。虽然可以使用 OPTIMIZE 查询运行非计划合并,但不要依赖它,因为 OPTIMIZE 查询会读取和写入大量数据。
因此,ReplacingMergeTree 适合在后台清除重复数据以节省空间,但不保证完全消除重复项。
关于 ReplacingMergeTree 的详细指南,包括最佳实践和优化性能的方法,请访问 此处。
创建表
有关请求参数的描述,请参阅 语句描述。
行的唯一性由 ORDER BY 表段确定,而不是 PRIMARY KEY。
ReplacingMergeTree 参数
ver
ver — 版本号列。类型为 UInt*、Date、DateTime 或 DateTime64。可选参数。
在合并时,ReplacingMergeTree 会在所有具有相同排序键的行中保留一个
- 如果没有设置
ver,则保留选择中的最后一个。选择是参与合并的一组 parts 中的一组行。最近创建的 part(最后一次插入)将是选择中的最后一个。因此,去重后,对于每个唯一的排序键,将保留来自最近一次插入的最后一个行。 - 如果指定了
ver,则保留具有最大版本的行。如果ver对于多行相同,则对它们应用“如果未指定ver”规则,即保留最近插入的行。
示例
is_deleted
is_deleted — 用于在合并期间确定此行中的数据是表示状态还是要删除的列的名称;1 表示“已删除”行,0 表示“状态”行。
列数据类型 — UInt8。
仅当使用 ver 时才能启用 is_deleted。
无论对数据进行何种操作,都应增加版本号。如果两个插入的行具有相同的版本号,则保留最后插入的行。
默认情况下,ClickHouse 会保留一个键的最后一个行,即使该行是删除行。这是为了确保将来具有较低版本的任何行都可以安全地插入,并且删除行仍然适用。
要永久删除这些删除行,请启用表设置 allow_experimental_replacing_merge_with_cleanup,并
-
设置表设置
enable_replacing_merge_with_cleanup_for_min_age_to_force_merge、min_age_to_force_merge_on_partition_only和min_age_to_force_merge_seconds。如果分区中的所有 parts 都比min_age_to_force_merge_seconds更旧,ClickHouse 会将它们全部合并到一个 part 中,并删除任何删除行。 -
或者手动运行
OPTIMIZE TABLE table [PARTITION partition | PARTITION ID 'partition_id'] FINAL CLEANUP。
示例
查询子句
创建 ReplacingMergeTree 表时,需要与创建 MergeTree 表时相同的 子句。
创建表的弃用方法
不要在新项目中使用此方法,如果可能,将旧项目切换到上述方法。
除了 ver 之外,所有参数的含义与 MergeTree 中的相同。
ver- 版本号列。可选参数。有关描述,请参阅上面的文本。
查询时去重 & FINAL
在合并时,ReplacingMergeTree 会识别重复的行,使用 ORDER BY 列的值(用于创建表)作为唯一标识符,并仅保留具有最高版本的行。但是,这仅提供最终正确性——它不能保证行将被去重,您不应依赖它。因此,由于更新和删除行被考虑在查询中,查询可能会产生不正确的结果。
为了获得正确的结果,用户需要将后台合并与查询时去重和删除删除补充。可以使用 FINAL 运算符来实现这一点。例如,考虑以下示例
在没有 FINAL 的情况下查询会产生不正确的计数(确切结果取决于合并)
添加 final 会产生正确的结果
有关 FINAL 的更多详细信息,包括如何优化 FINAL 性能,我们建议阅读我们的 ReplacingMergeTree 详细指南。