ReplacingMergeTree
このエンジンは、MergeTreeと異なり、同じソートキー値(ORDER BY
テーブルセクション、ではなくPRIMARY KEY
)を持つ重複エントリを削除します。
データの重複削除は、マージ中にのみ発生します。マージは不明な時間にバックグラウンドで行われるため、計画を立てることはできません。一部のデータは未処理のまま残ることがあります。OPTIMIZE
クエリを使用して非スケジュールのマージを実行することができますが、大量のデータを読み書きするため、これを利用することは期待しないでください。
したがって、ReplacingMergeTree
は、スペースを節約するためにバックグラウンドで重複データをクリアするのに適していますが、重複が存在しないことを保証するものではありません。
ReplacingMergeTreeに関する詳細なガイド、ベストプラクティス、パフォーマンスの最適化方法については、こちらをご覧ください。
テーブルの作成
リクエストパラメータの説明については、ステートメントの説明を参照してください。
行の一意性は、PRIMARY KEY
ではなく、ORDER BY
テーブルセクションによって決まります。
ReplacingMergeTreeのパラメータ
ver
ver
— バージョン番号を持つカラム。型はUInt*
、Date
、DateTime
またはDateTime64
。オプションのパラメータです。
マージ時に、ReplacingMergeTree
は同じソートキーを持つすべての行から1つだけを残します:
ver
が設定されていない場合は、選択内の最後の行が残ります。選択とは、マージに参加するパーツのセット内の行の集合です。最も最近作成されたパート(最後の挿入)が選択内の最後の行になります。したがって、重複削除後は、各ユニークなソートキーに対して、最新の挿入から最後の行が残ります。ver
が指定されている場合は、最大バージョンの行が残ります。複数の行が同じver
を持つ場合、それに対して「ver
が指定されていない場合」と同じルールが適用されるため、最も最近挿入された行が残ります。
例:
is_deleted
is_deleted
— マージ中に、データがこの行における状態か、削除されるべきかを判定するために使用されるカラムの名前;1
は「削除された」行、0
は「状態」行です。
カラムのデータ型はUInt8
です。
is_deleted
は、ver
が使用されている場合にのみ有効にできます。
データに対する操作に関わらず、バージョンは増加させる必要があります。挿入された2つの行が同じバージョン番号を持つ場合、最後に挿入された行が保持されます。
デフォルトでは、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
を設定します。パーティション内のすべてのパーツがmin_age_to_force_merge_seconds
よりも古い場合、ClickHouseはそれらをすべて1つのパートにマージし、削除行を取り除きます。 -
手動で
OPTIMIZE TABLE table [PARTITION partition | PARTITION ID 'partition_id'] FINAL CLEANUP
を実行します。
例:
クエリ句
ReplacingMergeTree
テーブルを作成する際には、MergeTree
テーブルを作成する際と同じ句が必要です。
テーブルを作成するための非推奨の方法
新しいプロジェクトではこの方法を使用せず、可能であれば古いプロジェクトを上記の方法に切り替えてください。
ver
を除くすべてのパラメータはMergeTree
と同じ意味を持ちます。
ver
- バージョンを持つカラム。オプションのパラメータです。詳細については、上記のテキストを参照してください。
クエリ時の重複排除とFINAL
マージ時に、ReplacingMergeTree
は重複した行を識別し、テーブル作成時に使用されたORDER BY
カラムの値を一意の識別子として利用し、最高バージョンのみを保持します。しかし、これは最終的に正しい結果を提供するものであり、行が重複しないことを保証するものではなく、これを期待すべきではありません。したがって、クエリは更新および削除行がクエリに考慮されるため、不正確な回答を生成することがあります。
正しい回答を得るには、ユーザーはバックグラウンドのマージを補完し、クエリ時の重複排除と削除処理を行う必要があります。これは、FINAL
演算子を使用することで達成できます。たとえば、次の例を考えます:
FINAL
を使わずにクエリを実行すると、不正確なカウントが生成されます(正確な結果はマージに応じて変わることがあります):
FINAL
を追加すると正しい結果が得られます:
FINAL
の詳細、パフォーマンスの最適化については、ReplacingMergeTreeに関する詳細ガイドをお読みになることをお勧めします。