6.5 KiB
slug | sidebar_position | sidebar_label | title |
---|---|---|---|
/ja/sql-reference/statements/alter/projection | 49 | PROJECTION | プロジェクション |
プロジェクションはクエリ実行を最適化する形式でデータを保存します。この機能は次の用途に便利です:
- 主キーの一部でないカラムに対するクエリの実行
- カラムの事前集計により、計算とIOの両方を削減
テーブルに対して1つ以上のプロジェクションを定義することができ、クエリ解析時にユーザーの指定したクエリを変更せずに、スキャンすべきデータが最小のプロジェクションをClickHouseが選択します。
:::note ディスク使用量
プロジェクションは内部で新しい隠しテーブルを作成するため、より多くのIOとディスクスペースが必要になります。 例として、異なる主キーを定義したプロジェクションがある場合、元のテーブルからのすべてのデータが複製されます。 :::
プロジェクションの内部動作に関する技術的な詳細はこのページをご覧ください。
主キーを使用せずにフィルタリングする例
テーブルの作成:
CREATE TABLE visits_order
(
`user_id` UInt64,
`user_name` String,
`pages_visited` Nullable(Float64),
`user_agent` String
)
ENGINE = MergeTree()
PRIMARY KEY user_agent
ALTER TABLE
を使って既存のテーブルにプロジェクションを追加することができます:
ALTER TABLE visits_order ADD PROJECTION user_name_projection (
SELECT
*
ORDER BY user_name
)
ALTER TABLE visits_order MATERIALIZE PROJECTION user_name_projection
データの挿入:
INSERT INTO visits_order SELECT
number,
'test',
1.5 * (number / 2),
'Android'
FROM numbers(1, 100);
プロジェクションを使用することで、元のテーブルでuser_name
がPRIMARY_KEY
として定義されていなくても、user_name
でのフィルタリングを素早く行えます。クエリ時にClickHouseは、プロジェクションを使用することでデータの処理量が少なくなると判断します。なぜなら、データがuser_name
でソートされているからです。
SELECT
*
FROM visits_order
WHERE user_name='test'
LIMIT 2
クエリがプロジェクションを使用しているか確認するには、system.query_log
テーブルを確認します。projections
フィールドには使用されたプロジェクションの名前が入り、未使用の場合は空になります:
SELECT query, projections FROM system.query_log WHERE query_id='<query_id>'
集計前のクエリの例
プロジェクションを使用してテーブルを作成:
CREATE TABLE visits
(
`user_id` UInt64,
`user_name` String,
`pages_visited` Nullable(Float64),
`user_agent` String,
PROJECTION projection_visits_by_user
(
SELECT
user_agent,
sum(pages_visited)
GROUP BY user_id, user_agent
)
)
ENGINE = MergeTree()
ORDER BY user_agent
データの挿入:
INSERT INTO visits SELECT
number,
'test',
1.5 * (number / 2),
'Android'
FROM numbers(1, 100);
INSERT INTO visits SELECT
number,
'test',
1. * (number / 2),
'IOS'
FROM numbers(100, 500);
user_agent
フィールドを使ったGROUP BY
クエリを最初に実行します。このクエリは事前集計が一致しないため、定義されたプロジェクションを使用しません。
SELECT
user_agent,
count(DISTINCT user_id)
FROM visits
GROUP BY user_agent
プロジェクションを使用するためには、事前集計またはGROUP BY
フィールドの一部またはすべてを選択するクエリを実行します。
SELECT
user_agent
FROM visits
WHERE user_id > 50 AND user_id < 150
GROUP BY user_agent
SELECT
user_agent,
sum(pages_visited)
FROM visits
GROUP BY user_agent
前述のように、system.query_log
テーブルを確認できます。projections
フィールドには使用されたプロジェクションの名前が入り、未使用の場合は空になります:
SELECT query, projections FROM system.query_log WHERE query_id='<query_id>'
プロジェクションの操作
次の操作がプロジェクションで利用可能です:
ADD PROJECTION
ALTER TABLE [db.]name [ON CLUSTER cluster] ADD PROJECTION [IF NOT EXISTS] name ( SELECT <COLUMN LIST EXPR> [GROUP BY] [ORDER BY] )
- テーブルのメタデータにプロジェクションの説明を追加します。
DROP PROJECTION
ALTER TABLE [db.]name [ON CLUSTER cluster] DROP PROJECTION [IF EXISTS] name
- テーブルのメタデータからプロジェクションの説明を削除し、プロジェクションのファイルをディスクから削除します。ミューテーションとして実装されています。
MATERIALIZE PROJECTION
ALTER TABLE [db.]table [ON CLUSTER cluster] MATERIALIZE PROJECTION [IF EXISTS] name [IN PARTITION partition_name]
- 指定されたパーティションpartition_name
内のプロジェクションname
を再構築します。ミューテーションとして実装されています。
CLEAR PROJECTION
ALTER TABLE [db.]table [ON CLUSTER cluster] CLEAR PROJECTION [IF EXISTS] name [IN PARTITION partition_name]
- 説明を削除せずにプロジェクションのファイルをディスクから削除します。ミューテーションとして実装されています。
ADD
、DROP
、CLEAR
コマンドはメタデータの変更やファイルの削除のみを行う軽量な操作です。
また、これらはClickHouse KeeperまたはZooKeeperを介してプロジェクションのメタデータを同期することによりレプリケーションされます。
:::note
プロジェクションの操作は*MergeTree
エンジン(レプリケートされたバリアントを含む)のテーブルでのみサポートされています。
:::