ほとんどの場合、パーティションキーは必要ありません。また、日単位でのパーティション化が一般的なオブザーバビリティのユースケースを除き、月単位より細かいパーティションキーも通常は不要です。細かすぎるパーティション化は決して使用しないでください。クライアント識別子や名前でデータをパーティション化してはいけません。代わりに、クライアント識別子または名前を ORDER BY 式の最初のカラムにしてください。
PARTITION BY expr 句で指定します。パーティションキーには、テーブルのカラムを使った任意の式を指定できます。たとえば、月単位のパーティション化を指定するには、toYYYYMM(date_column) 式を使用します。
マージは、パーティション化式の値が同じデータパーツに対してのみ実行されます。つまり、パーティションを細かくしすぎるべきではありません (目安は約 1,000 パーティション以下です) 。そうしないと、ファイルシステム内のファイル数や開かれたファイルディスクリプタが過剰になり、
SELECT クエリのパフォーマンスが低下します。visits テーブルがあるとします。system.parts テーブルに対して SELECT クエリを実行してみましょう。
partition カラムにはパーティション名が入ります。この例には 2 つのパーティションがあり、201901 と 201902 です。ALTER … PARTITION クエリでは、このカラムの値を使ってパーティション名を指定できます。
name カラムには、パーティションのデータパーツ名が入ります。ALTER ATTACH PART クエリでは、このカラムを使ってパーツ名を指定できます。
パーツ名 201901_1_9_2_11 を分解してみましょう。
201901はパーティション名です。1はデータブロックの最小番号です。9はデータブロックの最大番号です。2は chunk レベルです (このパーツの元になったマージツリーの深さ) 。11は mutation バージョンです (パーツが mutation された場合) 。
旧形式のテーブルのパーツ名は
20190117_20190123_2_2_0 です (最小日付 - 最大日付 - 最小ブロック番号 - 最大ブロック番号 - レベル) 。active カラムはパーツの状態を示します。1 はアクティブ、0 は非アクティブです。非アクティブなパーツには、たとえば、より大きなパーツにマージされたあとに残る元のパーツがあります。破損したデータパーツも非アクティブとして示されます。
例を見ると、同じパーティションに複数の独立したパーツがあることがわかります (たとえば 201901_1_3_1 と 201901_1_9_2) 。これは、これらのパーツがまだマージされていないことを意味します。ClickHouse は、挿入されたデータのパーツを定期的にマージします。通常、マージは挿入から約 15 分後に実行されます。また、OPTIMIZE クエリを使って、スケジュール外のマージを実行することもできます。例:
/var/lib/clickhouse/data/<database>/<table>/ に入ることです。例えば:
detached ディレクトリには、DETACH クエリを使ってテーブルからデタッチされたパーツが格納されます。破損したパーツも削除される代わりに、このディレクトリに移動されます。サーバーは detached ディレクトリ内のパーツを使用しません。ATTACH クエリを実行するまでは、このディレクトリ内のデータはいつでも追加、削除、変更できますが、サーバーはそれを認識しません。
稼働中のサーバーでは、ファイルシステム上でパーツの集合やそのデータを手動で変更することはできない点に注意してください。サーバーがその変更を認識しないためです。非レプリケートテーブルでは、サーバー停止中であればこれを行えますが、推奨されません。レプリケートテーブルでは、いかなる場合でもパーツの集合は変更できません。
ClickHouse では、パーティションに対して削除、あるテーブルから別のテーブルへのコピー、バックアップの作成といった操作を実行できます。すべての操作の一覧については、Manipulations With Partitions and Parts セクションを参照してください。
パーティションキーを使った Group By の最適化
このようなクエリのパフォーマンスは、テーブルのレイアウトに依存します。この最適化はバージョン 26.7 以降ではデフォルトで有効になっており、パーティションのレイアウトが不利な場合には、ランタイムヒューリスティクスによって自動的にスキップされます。具体的には、パーティション数が少なすぎる場合 (
max_threads / 2 未満)、パーティション数が多すぎる場合 (max_number_of_partitions_for_independent_aggregation より多い場合)、またはパーティションサイズの偏りが大きい場合 (最大のパーティションの行数が、総行数を max_threads で割った値の 2 倍を超える場合) です。以下の一覧では、一般に良好なパフォーマンスのためのレイアウト要因を説明しています。このうち、ランタイムヒューリスティクスで実際に適用されるのは、パーティション数とサイズの偏りだけです。- クエリに含まれるパーティション数が十分に多いこと (
max_threads / 2より大きいこと) 。そうでないと、クエリはマシンを十分に活用できません - パーティションが小さすぎないこと。そうしないと、バッチ処理が行単位の処理に近くなってしまいます
- パーティションのサイズが同程度であること。そうすることで、すべてのスレッドがほぼ同じ量の処理を行えます
データを各パーティションに均等に分散するために、
PARTITION BY 句のカラムに何らかのハッシュ関数を適用することを推奨します。allow_aggregate_partitions_independently- この最適化の使用を有効にするかどうかを制御しますforce_aggregate_partitions_independently- 正しさの観点では適用可能であるものの、その有効性を見積もる内部ロジックによって無効化される場合でも、使用を強制しますmax_number_of_partitions_for_independent_aggregation- テーブルが持てるパーティションの最大数に対するハードリミット