Snowflakeクラスタリングキーの検討方法:CLUSTERING_INFORMATIONの確認

Snowflakeでクラスタリングキーを設定するかの判断方法や設定手順をまとめました。
2022.02.07

こんにちは、データアナリティクス事業本部のnkhrです。

Snowflakeでクラスタリングキーを設定するか判断するための確認方法や設定手順をまとめました。

クラスタリングキー設定は必要?

下記の特徴を持つテーブルの場合、クラスタリングキーの設定が有効な場合があります。

  • 数TBレベルのデータ量を持つ大規模テーブルで、継続的なクエリパフォーマンスの低下
  • 上記テーブルにおいて、Clustering Average Depthが大きい(後の記載で説明します)

今回は2番目のClustering Average Depthの確認と、クラスタリングキーの設定方法について記載します。

大量データのクエリ効率化のためには、スキャン対象のデータ量を減らすことが重要です。Snowflakeではマイクロパーティションやデータクラスタリングという仕組みでスキャン対象データを減らすことができます。

公式ドキュメント:マイクロパーティションとデータクラスタリング

マイクロパーティションとは

  • Snowflakeは、データ取り込み時にマイクロパーティション(圧縮前で50~500 MBの小さな保存単位)にデータを分割保存します。
  • マイクロパーティションごとの情報(保持する列値の範囲や個数など)は、メタデータとして管理されます。
    • DML実行時に不要な範囲のデータを取得しない(プルーニング)に利用されます。
  • マイクロパーティション内のデータは、列ごとに独立して保存・圧縮されます(列志向ストレージ)。
  • サブクエリの場合は、メタデータを利用したプルーニングは実行されません。

データクラスタリングで消費するCreditについて

データクラスタリングでは、以下のCredit消費が発生します。

  • 計算リソース利用コスト
    • データクラスタリングを有効化すると、既存のデータや追加されたデータを再クラスタリング(並べ替え)するために計算リソースが消費されます(Snowflake側が管理する計算リソースのため、利用者側のウェアハウスは利用しない)
  • 増加ストレージコスト
    • 再クラスタリングでは、現在のマイクロパーティションの並べ替え、新しいマイクロパーティションが作成され、古いマイクロパーティションが削除されます。タイムトラベルやフェイルセーフが設定されている場合は、削除データを一定期間保持することにより、ストレージコストの増加が発生します。

データクラスタリングを有効にしておく期間や、コストに対するクエリ効率化の必要性を検討しておく必要があります。

クラスタリングキーの要否検討

Clustering Average Depth

理想的なマイクロパーティションの状態とは、各マイクロパーティションが持つデータの範囲が、他のマイクロパーティションとオーバーラップ(一部の範囲のみ重なる)しない状態です。しかしながら、現実にはそのような理想的な状態にはならないため、どの程度マイクロパーティションがオーバーラップしているかを図る指標としてClustering Average Depthを利用します。

Clustering Average Depthは、1またはそれ以上の数値となります。この値が大きいほど、データクラスタリングを実施した場合に、スキャン対象のマイクロパーティションを減らせれる可能性が高いです。(テーブルが空の場合は値は0です)

SYSTEM$CLUSTERING_INFORMATION

  • 実行クエリ
USE ROLE SYSADMIN;
SELECT SYSTEM$CLUSTERING_INFORMATION('SAMPLE_DB.PUBLIC.TRIPS', '(MEMBERSHIP_TYPE)')
  • 結果
{
  "cluster_by_keys" : "LINEAR(MEMBERSHIP_TYPE)",
  "total_partition_count" : 104,
  "total_constant_partition_count" : 86,
  "average_overlaps" : 2.9423,
  "average_depth" : 3.9423,
  "partition_depth_histogram" : {
    "00000" : 0,
    "00001" : 86,
    "00002" : 0,
    "00003" : 0,
    "00004" : 0,
    "00005" : 0,
    "00006" : 0,
    "00007" : 0,
    "00008" : 0,
    "00009" : 0,
    "00010" : 0,
    "00011" : 0,
    "00012" : 0,
    "00013" : 0,
    "00014" : 0,
    "00015" : 0,
    "00016" : 0,
    "00032" : 18
  }
}
  • total_partition_count マイクロパーティションの数。
  • total_constant_partition_count 再クラスタリングが必要ないパーティションの数。この数が多いとよい。
  • average_depth 平均深度。
    • 明確な基準はない(データ分布、テーブルの大きさ、ワークロード等にも依存)ですが、30以下だとまだ頑張れる!かもしれません
    • Average Depthのみを参照する場合は「SYSTEM$CLUSTERING_DEPTH」から取得できます
  • partition_depth_histogram 深度の分布

その他やったらよいこと

  • 設定前に対象テーブルに対するクエリセットを実行し、パフォーマンスのベースラインを確認
  • クエリのパフォーマンスをモニタリング(クラスタリング後にクエリパフォーマンスが改善しているかも確認)
  • Credit消費状況をモニタリング
  • ClusteringはALTER TABLEでSUSPEND/RESUMEを切り替えられるため、追加の都度にReClusteringが不要な場合は、Suspend/Resumeの切り替えを検討

クラスタリングキーの設定

CREATE TABLE

https://docs.snowflake.com/en/sql-reference/sql/create-table.html

create table test (date timestamp, id number, name varchar(10)) cluster by (date, id);
show tables like 'test';

ALTER TABLE

https://docs.snowflake.com/en/sql-reference/sql/alter-table.html

ALTER TABLE時はクラスタキーの新規設定以外に、再クラスタリングのSUSPEND/RESUMEやクラスタリングキーの削除を行えます。

  • CLUSTER BY ( expr [ , expr , ... ] )
  • SUSPEND | RESUME RECLUSTER
  • DROP CLUSTERING KEY
alter table test suspend recluster;
show tables like 'test';

まとめ

今回は、Snowflakeのデータクラスタリングの機能を整理しました。

あまり最初から有効にする必要はない機能っぽいですが、継続利用しているうちに必要になってくるかもしれません。クエリパフォーマンスのモニタリングなど通常の状態をモニタリングしておくことで、対応タイミングがわかるのかなと思います。

以上、nkhrでした。