低基数のパーティションキーを選択する
パーティショニングは主にデータ管理技術であり、クエリ最適化ツールではありません。特定のワークロードでパフォーマンスを向上させることができる一方で、クエリを加速させるための最初の手段として使用すべきではありません。パーティショニングキーは慎重に選択し、その影響を明確に理解した上で、データライフサイクルのニーズや十分に理解されたアクセスパターンと一致する場合にのみ適用されるべきです。
ClickHouseでは、パーティショニングは指定されたキーに基づいてデータを論理的なセグメントに整理します。これはテーブル作成時の PARTITION BY
句を使用して定義され、通常、時間間隔、カテゴリ、または他のビジネス関連次元によって行をグループ化するために使用されます。パーティショニング式の各ユニークな値は、ディスク上の独自の物理パーティションを形成し、ClickHouseはこれらの値ごとにデータを別々のパーツに保存します。パーティショニングはデータ管理を改善し、保持ポリシーを簡素化し、特定のクエリパターンに役立つことがあります。
例えば、次のパーティショニングキーとして toStartOfMonth(date)
を持つUKの支払価格データセットテーブルを考えてみましょう。
テーブルに一連の行が挿入されるたびに、すべての挿入された行を含む1つのデータパートを作成する代わりに(ここで説明されているように)、ClickHouseは挿入された行のユニークなパーティションキー値ごとに新しいデータパートを1つ作成します。

ClickHouseサーバは、上記の挿入の4行から構成される例の行を、そのパーティションキー値 toStartOfMonth(date)
によって最初に分割します。その後、特定された各パーティションについて、行は通常通りにいくつかの順次プロセス(① ソート、② カラムへの分割、③ 圧縮、④ ディスクへの書き込み)を実行して処理されます。
パーティショニングについての詳細な説明については、このガイドをお勧めします。
パーティショニングが有効な場合、ClickHouseはパーティション内のデータパーツのみをマージしますが、パーティション間ではマージしません。これを上記の例のテーブルに適用すると、次のようになります。

パーティショニングの適用
パーティショニングは、特に監視および分析のユースケースにおいて、ClickHouseの大規模データセットを管理するための強力なツールです。これは、時間やビジネスロジックに沿った全体のパーティションを1回のメタデータ操作で削除、移動、またはアーカイブできることで、効率的なデータライフサイクル操作を実現します。これは、行レベルの削除やコピー操作よりも大幅に速く、リソースを消費しません。パーティショニングは、TTLや層状ストレージなどのClickHouseの機能とクリーンに統合され、カスタムオーケストレーションなしで保持ポリシーやホット/コールドストレージ戦略を実装することができます。たとえば、最近のデータは速いSSDストレージに保持され、古いパーティションは自動的に安価なオブジェクトストレージに移動されます。
パーティショニングは、特定のワークロードでクエリパフォーマンスを向上させることがありますが、応答時間に悪影響を及ぼすこともあります。
パーティショニングキーが主キーに含まれておらず、そのキーで絞り込みを行う場合、ユーザーはパーティショニングによってクエリパフォーマンスが向上するのを感じることがあるかもしれません。例については、こちらを参照してください。
逆に、クエリがパーティションをまたいで行なわれる必要がある場合、合計パーツ数の増加によりパフォーマンスが悪化することがあります。このため、ユーザーはパーティショニングをクエリ最適化技術として検討する前に、自身のアクセスパターンを理解しておくべきです。
要約すると、ユーザーは主にパーティショニングをデータ管理技術として考えるべきです。データ管理の例については、監視ユースケースガイドの"データの管理"およびコアコンセプト - テーブルパーティションの"テーブルパーティションは何に使用されるか?"を参照してください。
低カーディナリティのパーティショニングキーを選択する
重要なのは、パーツの数が多いとクエリパフォーマンスに悪影響を及ぼすことです。したがって、ClickHouseは、総数またはパーティションごとの数が指定された制限を超えると、「パーツが多すぎる」エラーで応答します。
パーティショニングキーに適切なカーディナリティを選択することは重要です。特異なパーティション値の数が多い高カーディナリティのパーティショニングキーは、データパーツの proliferate を引き起こす可能性があります。ClickHouse はパーティション間でパーツをマージしないため、パーティションが多すぎると、マージされていないパーツが多すぎる結果となり、「パーツが多すぎる」エラーが発生します。マージは重要です ストレージの断片化を減少させ、クエリ速度を最適化するために必要ですが、高カーディナリティのパーティションでは、マージの可能性が失われます。
対照的に、低カーディナリティのパーティショニングキー(100〜1,000の異なる値未満)は通常最適です。これにより、効率的なパートのマージが可能になり、メタデータのオーバーヘッドを低く保ち、ストレージ内での過剰なオブジェクト作成を回避できます。さらに、ClickHouseはパーティションカラムに自動的にMinMaxインデックスを構築するため、これらのカラムでフィルタリングするクエリの速度が大幅に向上します。たとえば、テーブルが toStartOfMonth(date)
によってパーティショニングされている場合、月でフィルタリングすることで、エンジンは無関係なパーティションとそのパーツを完全にスキップすることができます。
パーティショニングは、いくつかのクエリパターンでパフォーマンスを改善することができますが、主にデータ管理機能です。多くの場合、すべてのパーティションをまたぐクエリは、データの断片化が増し、スキャンされるパーツが増えるため、非パーティショニングテーブルを使用するよりも遅くなる場合があります。パーティショニングは賢く使い、選択したキーが低カーディナリティであり、データライフサイクルポリシー(例えば、TTLによる保持)と整合していることを常に確認してください。パーティショニングが必要かどうかわからない場合は、まずはそれなしで始め、観察されたアクセスパターンに基づいて後で最適化を行うことをお勧めします。