パーティション
PARTITION BY 句で指定します。この句には、任意のカラムに対する SQL 式を含めることができ、その結果によって各行の格納先となるパーティションが決まります。
データパーツは、ディスク上で各パーティションに論理的に関連付けられており (共通のフォルダー名プレフィックスを介して) 、個別にクエリできます。以下の例では、デフォルトの otel_logs スキーマは、toDate(Timestamp) 式を使って日単位でパーティション化されています。行が ClickHouse に挿入されるたびに、この式が各行に対して評価され、対応するパーティションが存在すればそのパーティションに振り分けられます (その日の最初の行であれば、パーティションが作成されます) 。
otel_logs テーブルが日単位でパーティション分割されているとします。ここに構造化されたログデータセットを投入すると、数日分のデータが含まれます。
otel_logs_archive を用意している場合があります。データはパーティション単位でこのテーブルへ効率的に移動できます (これは単なるメタデータ変更です) 。
INSERT INTO SELECT を使用し、新しいターゲットテーブルにデータを書き換える必要がある他の手法とは対照的です。
パーティションの移動テーブル間でパーティションを移動するには、いくつかの条件を満たす必要があります。特に、テーブルの構造、パーティションキー、主キー、インデックス/プロジェクションが同一でなければなりません。
ALTER DDL でパーティションをどのように指定するかについての詳しい注意事項は、こちらを参照してください。この機能は、設定
ttl_only_drop_parts=1 を使用すると、有効期限 (TTL) によって利用されます。詳細については、有効期限 (TTL) を使用したデータ管理 を参照してください。適用例
- 階層型アーキテクチャ - データをストレージ階層間で移動し (ストレージティア を参照) 、ホット・コールド構成を実現できます。
- 効率的な削除 - データが指定した有効期限 (TTL) に達した場合 (Data management with TTL を参照)
クエリパフォーマンス
有効期限 (TTL) によるデータ管理
テーブルレベルの有効期限 (TTL)
ttl キーで指定します (例) 。
h を使用し、パーティション化の期間に合わせることを推奨します。たとえば、日単位でパーティション化している場合は、日数の倍数になるようにしてください (例: 24h、48h、72h) 。 これにより、たとえば ttl: 96h の場合、テーブルに有効期限 (TTL) 句が自動的に追加されます。
有効期限 (TTL) のスケジュール有効期限 (TTL) は、前述のとおり即座には適用されず、スケジュールに従って適用されます。MergeTree テーブル設定
merge_with_ttl_timeout は、delete 有効期限 (TTL) を伴うマージを再実行するまでの最小待機時間を秒単位で設定します。デフォルト値は 14400 秒 (4 時間) です。ただし、これはあくまで最小待機時間にすぎず、有効期限 (TTL) マージがトリガーされるまでさらに時間がかかることがあります。値が低すぎると、リソースを大量に消費する可能性のあるスケジュール外のマージが多数実行されます。有効期限 (TTL) の期限切れは、コマンド ALTER TABLE my_table MATERIALIZE TTL で強制できます。ttl_only_drop_parts=1 設定の使用を推奨します (デフォルトのスキーマで適用されます) 。この設定を有効にすると、ClickHouse は、その中のすべての行の有効期限が切れている場合、パーツ全体を削除します。有効期限 (TTL) 切れの行を部分的にクリーンアップする代わりにパーツ全体を削除することで (ttl_only_drop_parts=0 の場合は、リソース負荷の高い mutation によって処理されます) 、merge_with_ttl_timeout をより短く設定でき、システム性能への影響も抑えられます。有効期限 (TTL) の期限切れを行う単位 (たとえば日単位) と同じ単位でデータをパーティション化していれば、パーツには自然にその期間のデータだけが含まれるようになります。これにより、ttl_only_drop_parts=1 を効率よく適用できます.
カラムレベルの有効期限 (TTL)
Body カラムは保持しておくことを推奨します。たとえば、新しい Kubernetes label などです。一定期間、たとえば 1 か月が経過すると、この追加メタデータが有用でないことが明らかになる場合があります。そうなると、Body カラムを保持しておく価値は限定的になります。
以下では、Body カラムを 30 日後に削除する方法を示します。
カラムレベルの有効期限 (TTL) を指定するには、独自のスキーマを定義する必要があります。これは OTel collector では指定できません。
データの再圧縮
ZSTD(1) を推奨していますが、別の圧縮アルゴリズムや、たとえば ZSTD(3) のようなより高い圧縮レベルを試すこともできます。これはスキーマ作成時に指定できるだけでなく、一定期間の経過後に圧縮設定を変更するよう構成することも可能です。これは、コーデックや圧縮アルゴリズムによって圧縮率は向上するものの、クエリのパフォーマンスが低下する場合に適しています。このトレードオフは、参照頻度の低い古いデータでは許容できても、調査でより頻繁に使用される新しいデータには適さない可能性があります。
以下にその例を示します。ここでは、データを削除する代わりに、4 日後に ZSTD(3) で圧縮します。
パフォーマンスを評価するさまざまな圧縮レベルやアルゴリズムが、インサートおよびクエリのパフォーマンスに与える影響は、必ず両方を評価することを推奨します。たとえば、delta codec はタイムスタンプの圧縮に有効な場合があります。ただし、それらが主キーの一部である場合、フィルタリングのパフォーマンスが低下することがあります。
ストレージティア
ClickHouse Cloud には該当しませんClickHouse Cloud では、S3 に保存された単一のデータコピーと、SSD ベースのノード cache を使用します。そのため、ClickHouse Cloud でストレージティアは不要です。
ALTER TABLE MOVE PARTITION コマンドを使ってディスク間で手動移動できますが、ボリューム間のデータ移動は有効期限 (TTL) で制御することもできます。完全な例はこちらにあります。
スキーマ変更の管理
デフォルト値を使用する
DEFAULT values を使って、カラムをスキーマに追加できます。指定されたデフォルト値は、INSERT 時に値が指定されなかった場合に使用されます。
スキーマの変更は、materialized view の変換ロジックや OTel collector の設定を変更する前に行えます。これにより、新しいカラムを送信できるようになります。
スキーマを変更したら、OTel collectors を再設定できます。ここでは、ユーザーが “Extracting structure with SQL” で説明されている推奨プロセス、つまり OTel collectors がデータを Null table engine に送信し、materialized view がターゲットスキーマを抽出して、その結果を保存先のターゲットテーブルに送る構成を使用しているものとします。この場合、ビューは ALTER TABLE ... MODIFY QUERY syntax を使って変更できます。たとえば、OTel の構造化ログからターゲットスキーマを抽出するために、以下のターゲットテーブルと、それに対応する materialized view (“Extracting structure with SQL” で使用しているものと同様) を考えてみましょう。
LogAttributes から新しいカラム Size を抽出するとします。これは ALTER TABLE を使ってスキーマに追加し、デフォルト値を指定できます。
LogAttributes 内の size キーを指定しています (存在しない場合は 0 になります) 。つまり、このカラムにアクセスするクエリでは、その値が挿入されていない行については Map にアクセスする必要があるため、処理が遅くなります。これを定数、たとえば 0 として指定することも簡単にでき、その値を持たない行に対する後続のクエリのコストを削減できます。このテーブルをクエリすると、Map から期待どおりに値が設定されていることがわかります。
ALTER TABLE 構文を使って materialized view を変更できます。
Size カラムに値が設定されます。
新しいテーブルを作成する
ALTER TABLE MODIFY QUERY. を使って新しいテーブルを参照するように変更できます。この方法を使えば、たとえば otel_logs_v3 のようにテーブルをバージョン管理できます。
この方法では、ユーザーはクエリ対象のテーブルを複数扱うことになります。複数のテーブルをまたいでクエリするには、テーブル名にワイルドカードパターンを指定できる merge 関数 を使用できます。以下では、otel_logs テーブルの v2 と v3 をクエリする例を示します。
merge 関数の使用を避けたい場合は、Merge テーブルエンジンを使用できます。以下でこれを示します。
EXCHANGEテーブル構文を使って更新できます。たとえば、v4テーブルを追加するには、新しいテーブルを作成し、これを前のバージョンとアトミックに入れ替えることができます。