メインコンテンツまでスキップ
メインコンテンツまでスキップ

AggregatingMergeTree

このエンジンは MergeTree から継承され、データパーツのマージに関するロジックを変更します。ClickHouse は、同じ主キー(または正確には、同じ ソートキー)を持つすべての行を、集約関数の状態の組み合わせを保存する単一の行(単一のデータパート内)に置き換えます。

AggregatingMergeTree テーブルを使用して、集計されたマテリアライズドビューを含む増分データ集計を行うことができます。

以下のビデオでは、AggregatingMergeTree と集約関数の使用例を見ることができます:

このエンジンは、以下のタイプのすべてのカラムを処理します:

行数をオーダー単位で削減できる場合に AggregatingMergeTree を使用するのが適切です。

テーブルの作成

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

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

クエリ句

AggregatingMergeTree テーブルを作成する場合、MergeTree テーブルを作成する場合と同じ が必要です。

テーブル作成のための非推奨メソッド
注記

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

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

すべてのパラメータは MergeTree と同じ意味を持ちます。

SELECT と INSERT

データを挿入するには、集約 -State- 関数を使った INSERT SELECT クエリを使用します。AggregatingMergeTree テーブルからデータを選択する際は、GROUP BY 句を使用し、挿入時と同じ集約関数を使用しますが、-Merge サフィックスを付けます。

SELECT クエリの結果では、AggregateFunction タイプの値はすべての ClickHouse 出力フォーマットに対して実装固有のバイナリ表現を持っています。例えば、SELECT クエリでデータを TabSeparated フォーマットにダンプすると、このダンプは INSERT クエリを使用して再度読み込むことができます。

集約されたマテリアライズドビューの例

以下の例では、test というデータベースがあると仮定しています。存在しない場合は、以下のコマンドで作成してください:

CREATE DATABASE test;

次に、原データを含むテーブル test.visits を作成します:

CREATE TABLE test.visits
 (
    StartDate DateTime64 NOT NULL,
    CounterID UInt64,
    Sign Nullable(Int32),
    UserID Nullable(Int32)
) ENGINE = MergeTree ORDER BY (StartDate, CounterID);

次に、訪問回数とユニークユーザー数を追跡する AggregationFunctions を保存する AggregatingMergeTree テーブルが必要です。

test.visits テーブルを監視し、AggregateFunction タイプを使用する AggregatingMergeTree マテリアライズドビューを作成します:

CREATE TABLE test.agg_visits (
    StartDate DateTime64 NOT NULL,
    CounterID UInt64,
    Visits AggregateFunction(sum, Nullable(Int32)),
    Users AggregateFunction(uniq, Nullable(Int32))
)
ENGINE = AggregatingMergeTree() ORDER BY (StartDate, CounterID);

test.visits から test.agg_visits にデータを埋め込むマテリアライズドビューを作成します:

CREATE MATERIALIZED VIEW test.visits_mv TO test.agg_visits
AS SELECT
    StartDate,
    CounterID,
    sumState(Sign) AS Visits,
    uniqState(UserID) AS Users
FROM test.visits
GROUP BY StartDate, CounterID;

test.visits テーブルにデータを挿入します:

INSERT INTO test.visits (StartDate, CounterID, Sign, UserID)
 VALUES (1667446031000, 1, 3, 4), (1667446031000, 1, 6, 3);

データは test.visitstest.agg_visits の両方に挿入されます。

集約データを取得するには、マテリアライズドビュー test.visits_mv から SELECT ... GROUP BY ... のようなクエリを実行します:

SELECT
    StartDate,
    sumMerge(Visits) AS Visits,
    uniqMerge(Users) AS Users
FROM test.visits_mv
GROUP BY StartDate
ORDER BY StartDate;
┌───────────────StartDate─┬─Visits─┬─Users─┐
│ 2022-11-03 03:27:11.000 │      9 │     2 │
└─────────────────────────┴────────┴───────┘

test.visits にさらに別のレコードを追加しますが、一方のレコードには異なるタイムスタンプを使ってみてください:

INSERT INTO test.visits (StartDate, CounterID, Sign, UserID)
 VALUES (1669446031000, 2, 5, 10), (1667446031000, 3, 7, 5);

再度 SELECT クエリを実行すると、次の出力が返されます:

┌───────────────StartDate─┬─Visits─┬─Users─┐
│ 2022-11-03 03:27:11.000 │     16 │     3 │
│ 2022-11-26 07:00:31.000 │      5 │     1 │
└─────────────────────────┴────────┴───────┘

場合によっては、挿入時に行を事前集約することを避けて、集約のコストを挿入時からマージ時に移すことが望ましいことがあります。通常、エラーを避けるために、マテリアライズドビュー定義の GROUP BY 句に集約に含まれないカラムを含める必要があります。しかし、optimize_on_insert = 0(デフォルトでオンになっています)の設定で initializeAggregation 関数を利用することでこれを達成できます。この場合には GROUP BY の使用はもはや必要ありません:

CREATE MATERIALIZED VIEW test.visits_mv TO test.agg_visits
AS SELECT
    StartDate,
    CounterID,
    initializeAggregation('sumState', Sign) AS Visits,
    initializeAggregation('uniqState', UserID) AS Users
FROM test.visits;
注記

initializeAggregation を使用すると、グループ化せずに個々の行ごとに集約状態が作成されます。 各ソース行はマテリアライズドビューに1行を生成し、実際の集約は後で AggregatingMergeTree がパーツをマージするときに行われます。これは optimize_on_insert = 0 の場合にのみ当てはまります。