Skip to main content
このエンジンは、同じソートキーの値 (PRIMARY KEY ではなく、テーブル定義の ORDER BY セクション) を持つ重複エントリを削除する点で、MergeTreeと異なります。 データの重複排除が行われるのは、マージ時のみです。マージはバックグラウンドでいつ行われるか分からないため、それを前提に計画することはできません。データの一部が未処理のまま残る可能性があります。OPTIMIZE クエリを使って臨時にマージを実行することはできますが、OPTIMIZE クエリでは大量のデータの読み書きが発生するため、これに頼るべきではありません。 したがって、ReplacingMergeTree は容量を節約するためにバックグラウンドで重複データを除去する用途には適していますが、重複が存在しないことを保証するものではありません。
ベストプラクティスやパフォーマンスの最適化方法を含む ReplacingMergeTree の詳細なガイドは、こちらで確認できます。

テーブルの作成

リクエストパラメーターの説明については、ステートメントの説明を参照してください。
行の一意性は、PRIMARY KEY ではなく、テーブルの ORDER BY セクションによって決まります。

ReplacingMergeTree パラメータ

ver

ver — バージョン番号を表すカラムです。型は UInt*DateDateTimeDateTime64 のいずれかです。省略可能なパラメータです。 マージ時、ReplacingMergeTree は同じソートキーを持つすべての行の中から 1 行だけを残します。
  • ver が設定されていない場合は、選択対象内の最後の行が残ります。選択対象とは、マージに参加する一連のパーツに含まれる行の集合です。最も後に作成されたパーツ (最後の insert) が選択対象の最後になります。したがって、重複排除後は、各一意のソートキーについて、直近の insert で追加された最後の行が残ります。
  • ver が指定されている場合は、最大のバージョンを持つ行が残ります。複数の行で ver が同じ場合は、それらには “ver が設定されていない場合” のルールが適用されます。つまり、最も新しく挿入された行が残ります。
例:

is_deleted

is_deleted — マージ時に、この行のデータが state を表すのか、削除対象なのかを判定するために使用されるカラム名です。1 は “deleted” 行、0 は “state” 行です。 カラムのデータ型 — UInt8
is_deleted は、ver を使用している場合にのみ有効にできます。データに対してどのような操作を行う場合でも、バージョンは増やす必要があります。挿入された 2 つの行のバージョン番号が同じ場合は、最後に挿入された行が保持されます。デフォルトでは、ClickHouse は、その行が削除行であっても、あるキーに対する最後の行を保持します。これは、今後それより低いバージョンの行が 安全に挿入されても、その削除行が引き続き適用されるようにするためです。そのような削除行を永続的に削除するには、テーブル設定 allow_experimental_replacing_merge_with_cleanup を有効にし、次のいずれかを行います。
  1. テーブル設定 enable_replacing_merge_with_cleanup_for_min_age_to_force_mergemin_age_to_force_merge_on_partition_onlymin_age_to_force_merge_seconds を設定します。パーティション内のすべてのパーツが min_age_to_force_merge_seconds より古い場合、ClickHouse はそれらを すべて 1 つのパーツにマージし、削除行を取り除きます。
  2. OPTIMIZE TABLE table [PARTITION partition | PARTITION ID 'partition_id'] FINAL CLEANUP を手動で実行します。
例:

クエリ句

ReplacingMergeTree テーブルの作成時には、MergeTree テーブルの作成時と同じ が必要です。

クエリ時の重複排除 & FINAL

マージ時には、ReplacingMergeTree が重複する行を識別し、テーブル作成時に指定した ORDER BY カラムの値を一意の識別子として、最も大きいバージョンだけを保持します。ただし、これで保証されるのはあくまで結果整合性のみであり、行が確実に重複排除されるわけではないため、これに依存すべきではありません。そのため、更新行や削除行もクエリ時に考慮されることで、クエリ結果が不正確になる可能性があります。 正しい結果を得るには、バックグラウンドマージに加えて、クエリ時の重複排除と削除行の除去を行う必要があります。これは FINAL 演算子を使って実現できます。たとえば、次の例を見てみましょう。
FINAL を使用せずにクエリすると、件数が正しくなりません (実際の結果はマージの状況によって異なります) :
FINAL を追加すると、正しい結果になります:
FINAL の詳細や、そのパフォーマンスを最適化する方法については、ReplacingMergeTree の詳細ガイドを参照することをお勧めします。
最終更新日 2026年7月23日