Skip to main content

ReplacingMergeTree

このエンジンは、MergeTreeと異なり、同じソートキーの値を持つ重複エントリを削除します(PRIMARY KEYではなく、テーブルのORDER BYセクション)。

データの重複排除はマージの際にのみ発生します。マージは背景で不明な時点で発生するため、計画することはできません。一部のデータは未処理のまま残る可能性があります。OPTIMIZEクエリを使用して予定外のマージを実行することができますが、大量のデータを読み書きするため、これに依存しないでください。

したがって、ReplacingMergeTreeは重複データを背景で削除し、スペースを節約するのに適していますが、重複が存在しないことを保証するものではありません。

Note

ReplacingMergeTreeの詳細ガイドにはベストプラクティスやパフォーマンスの最適化方法も含まれており、こちらで利用可能です。

テーブルの作成

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = ReplacingMergeTree([ver [, is_deleted]])
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]

リクエストパラメータの説明については、ステートメントの説明を参照してください。

Note

行の一意性はPRIMARY KEYではなく、テーブルのORDER BYセクションによって決定されます。

ReplacingMergeTree パラメーター

ver

ver — バージョン番号を持つカラム。タイプは UInt*DateDateTimeまたはDateTime64です。オプションのパラメーターです。

マージ時に、ReplacingMergeTreeは同じソートキーを持つ行の中から1つだけを残します:

  • verが設定されていない場合、選択されたものの最後のもの。選択は、マージに参加しているパーツの集合からなる行の集合です。最も最近に作成されたパーツ(最後の挿入)が選択の最後になります。したがって、重複処理後、最も最近の挿入から来る最後の行が各ユニークなソートキーに残ります。
  • verが指定されている場合は、最大のバージョン。もし複数の行でverが同じであれば、「verが指定されていない場合」のルールが適用されます、すなわち、最も最近に挿入された行が残ります。

例:

-- verなし - 最後に挿入された行が残る
CREATE TABLE myFirstReplacingMT
(
`key` Int64,
`someCol` String,
`eventTime` DateTime
)
ENGINE = ReplacingMergeTree
ORDER BY key;

INSERT INTO myFirstReplacingMT Values (1, 'first', '2020-01-01 01:01:01');
INSERT INTO myFirstReplacingMT Values (1, 'second', '2020-01-01 00:00:00');

SELECT * FROM myFirstReplacingMT FINAL;

┌─key─┬─someCol─┬───────────eventTime─┐
1second2020-01-01 00:00:00
└─────┴─────────┴─────────────────────┘


-- ver使用 - 最大のverを持つ行が残る
CREATE TABLE mySecondReplacingMT
(
`key` Int64,
`someCol` String,
`eventTime` DateTime
)
ENGINE = ReplacingMergeTree(eventTime)
ORDER BY key;

INSERT INTO mySecondReplacingMT Values (1, 'first', '2020-01-01 01:01:01');
INSERT INTO mySecondReplacingMT Values (1, 'second', '2020-01-01 00:00:00');

SELECT * FROM mySecondReplacingMT FINAL;

┌─key─┬─someCol─┬───────────eventTime─┐
1first2020-01-01 01:01:01
└─────┴─────────┴─────────────────────┘

is_deleted

is_deleted — この行のデータが状態を表しているか削除されるべきかを決定するためにマージ中に使用されるカラムの名前:1は"削除"された行、0は"状態"の行。

カラムデータ型 — UInt8

Note

is_deletedverを使用している場合にのみ有効にできます。

行はOPTIMIZE ... FINAL CLEANUPでのみ削除されます。このCLEANUP特別キーワードは、デフォルトでは許可されていませんが、allow_experimental_replacing_merge_with_cleanup MergeTree設定を有効にすると使用できます。

データに対する操作が何であれ、バージョンは増加しなければなりません。同じバージョン番号を持つ二つの挿入された行がある場合、最後に挿入された行が残ります。

例:

-- verとis_deletedで
CREATE OR REPLACE TABLE myThirdReplacingMT
(
`key` Int64,
`someCol` String,
`eventTime` DateTime,
`is_deleted` UInt8
)
ENGINE = ReplacingMergeTree(eventTime, is_deleted)
ORDER BY key
SETTINGS allow_experimental_replacing_merge_with_cleanup = 1;

INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 01:01:01', 0);
INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 01:01:01', 1);

select * from myThirdReplacingMT final;

0 rows in set. Elapsed: 0.003 sec.

-- is_deletedを持つ行を削除
OPTIMIZE TABLE myThirdReplacingMT FINAL CLEANUP;

INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 00:00:00', 0);

select * from myThirdReplacingMT final;

┌─key─┬─someCol─┬───────────eventTime─┬─is_deleted─┐
1first2020-01-01 00:00:000
└─────┴─────────┴─────────────────────┴────────────┘

クエリの条項

ReplacingMergeTreeテーブルを作成する際には、MergeTreeテーブルを作成する場合と同じ条項が必要です。

非推奨のテーブル作成方法
Note

新しいプロジェクトではこの方法を使用せず、可能であれば古いプロジェクトを上記の方法に切り替えてください。

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE [=] ReplacingMergeTree(date-column [, sampling_expression], (primary, key), index_granularity, [ver])

verを除くすべてのパラメーターは、MergeTreeの場合と同じ意味を持ちます。

  • ver - バージョンを持つカラム。オプションのパラメーター。説明については上記のテキストをご覧ください。

クエリ時間の重複排除 & FINAL

マージ時に、ReplacingMergeTreeはORDER BYカラムの値をユニークな識別子として使用して重複行を識別し、最高のバージョンのみを保持します。しかしながら、これは事後的に正しさを提供するのみであり、行が重複排除されることを保証するものではないため、これに頼るべきではありません。したがって、クエリは問題が発生する可能性があるため、適切な回答を得るためにはバックグラウンドでのマージとクエリ時間での重複排除と削除の排除を補完する必要があります。これはFINAL演算子を使用して可能です。以下の例を考えてみてください:

CREATE TABLE rmt_example
(
`number` UInt16
)
ENGINE = ReplacingMergeTree
ORDER BY number

INSERT INTO rmt_example SELECT floor(randUniform(0, 100)) AS number
FROM numbers(1000000000)

0 rows in set. Elapsed: 19.958 sec. Processed 1.00 billion rows, 8.00 GB (50.11 million rows/s., 400.84 MB/s.)

FINALなしでクエリを実行すると、不正確な数が出力されます(正確な結果はマージ状況によって異なります):

SELECT count()
FROM rmt_example

┌─count()─┐
200
└─────────┘

1 row in set. Elapsed: 0.002 sec.

FINALを追加すると、正しい結果が得られます:

SELECT count()
FROM rmt_example
FINAL

┌─count()─┐
100
└─────────┘

1 row in set. Elapsed: 0.002 sec.

FINALおよびその最適化方法についてより詳細な情報は、ReplacingMergeTreeの詳細ガイドを参照することをお勧めします。