【Snowflake】Snowflakeのパフォーマンス改善 ~ クラスタリングキー ~

■ はじめに

https://dk521123.hatenablog.com/entry/2022/12/07/111847
https://dk521123.hatenablog.com/entry/2023/02/27/120943

の続き。

 今回は、クラスタリングキーおよび
その周辺に関わるマイクロパーティションについて
自分なりにまとめてみる

なお、「プルーニング」、「マイクロパーティション」については
以下の関連記事を参照のこと

Snowflakeのパフォーマンス改善 ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2023/09/20/002235

目次

【0】自分の中でのざっくりした勝手な理解
 1)マイクロパーティションに関するざっくり理解
 2)データクラスタリングに関するざっくり理解
 3)クラスタリングキーに関するざっくり理解
【1】ニアゼロメンテナンス
 1)マイクロパーティション
 2)データクラスタリング
【2】クラスタリングキー
 1)クラスタリングキーの有効性(利点)
 2)使用上の注意
 3)どういった場合に指定した方がいい?
 4)クラスタリングキーの操作
 5)自動クラスタリング

【0】自分の中でのざっくりした勝手な理解

調べながら、つらつらと書いたら、
もの凄く長くなってしまった(【1】以降)ので、
まずは、自分が理解したざっくりしたことを書いておく。

1)マイクロパーティションに関するざっくり理解

* Snowflake では、デフォルトで「マイクロパーティション」という
 ストレージ単位で自動的にデータ分割される
 => これにより、無駄なデータスキャンを極力省き、
  パフォーマンス向上になっている
 => 詳細は、以下の関連記事を参照のこと

Snowflakeのパフォーマンス改善 ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2023/09/20/002235

2)データクラスタリングに関するざっくり理解

* Snowflake では、デフォルトで
 データ間の類似度に基づいてデータをグループ分けしてくれる
 => これにより、「マイクロパーティション」で言ってた
 『無駄なデータスキャンを極力省き』を効率に行える
 => ちょっと違うかもしれないが、OSの「デフラグ」みたいな感じ?

3)クラスタリングキーに関するざっくり理解

* 「マイクロパーティション」と「データクラスタリング」により、
 クエリのパフォーマンス向上をデフォルトで行ってくれるが
 時間の経過とともに、非常に大きなテーブル(行数ではなくテーブル内のデータ量)
 において、一部のテーブル行のデータがにクラスタ化されなくなる場合があり、
 パフォーマンスが劣化する

 => 解決するために、テーブルに併せた項目について、
  クラスタリングキーを指定し、対策することが可能

【1】ニアゼロメンテナンス

Snowflakeでは、以下が自動で適用される
~~~~~~~
1)マイクロパーティション
2)データクラスタリング
~~~~~~~
 => 上記の仕組みにより、スキャン対象データを減らし、
  大量データのクエリ効率に役立つ
 => Snowflakeが掲げる「ニアゼロメンテナンス」を実現
 (ただし、あくまで「ニアゼロ(Near Zero=おおよそ無し)」)

公式サイトより
https://www.snowflake.com/snowflake-cloud-data-platform/?lang=ja

~~~~~~~
サービスとしてのニアゼロメンテナンス

Snowflakeは他のソリューションと違い、
お客様によるメンテナンスがほとんど必要ありません。
構築、インデックス作成、パーティショニングスキームの管理といった
従来のデータベースタスクが不要になります。
~~~~~~~

1)マイクロパーティション

Snowflake は、コンピュートとストレージが分離したアーキテクチャを採用
そのため、データの読み込みがボトルネックとなるケースが多い

 => Snowflakeでは、マイクロパーティショニングを採用することによって
  効果的なプルーニングを可能にし、不要な読み込みを回避

 => そのため、snowflakeのパフォーマンンスを改善する上で
  マイクロパーティションは重要になる

マイクロパーティション / プルーニング とは?

* 以下の関連記事を参照のこと

https://dk521123.hatenablog.com/entry/2023/09/20/002235

2)データクラスタリング

データ間の類似度にもとづいて、
データ(例えば、日付や地理的地域など)をグループ分けする

https://docs.snowflake.com/ja/user-guide/tables-clustering-micropartitions#what-is-data-clustering

【2】クラスタリングキー

 Snowflake では、非常に大きなテーブルなどで、
マイクロパーティションが構成されなくなった場合に、
明示的にクラスタリングキーを指定することができる

https://docs.snowflake.com/ja/user-guide/tables-clustering-keys

1)クラスタリングキーの有効性(利点)

https://docs.snowflake.com/ja/user-guide/tables-clustering-keys#benefits-of-defining-clustering-keys-for-very-large-tables

[1] クエリのスキャン効率が向上することにより
 データをスキップすること効率的になりパフォーマンス向上

[2] クラスタリングのないテーブルよりも列圧縮が向上

[3] クラスタリングキーを削除/変更しない限り、追加の管理は必要ない
 => 後述「5)自動クラスタリング」を参照

2)使用上の注意

https://docs.snowflake.com/ja/user-guide/tables-clustering-keys#strategies-for-selecting-clustering-keys

* 無暗やたらと全てのテーブルに適用するものではない
 => クラスタリングを維持するコストがかかるため

* 1テーブルに対して、最大3 or 4列を推奨
 => 推奨値を超えると、利益よりもコストが増加する傾向があるため

* カーディナリティが非常に低い列(例:男性か女性かのみを示す列)は、
 クラスタリングキーとして直接使用する候補には 適していない

https://docs.snowflake.com/ja/user-guide/tables-clustering-keys#label-considerations-for-choosing-clustering

* クラスタリングキーを適用する前に、
 対象テーブルで代表的なクエリセットを
 パフォーマンステストしておき、記録として残しておいた方がいい
 => 適用後、同じクエリでテストし、比較することにより、
  コストに見合うパフォーマンスだったかの検討材料になる

3)どういった場合に指定した方がいい?

* テーブルがTB級の巨大なテーブルで、クエリパフォーマンスが悪い場合

https://docs.snowflake.com/ja/user-guide/tables-clustering-keys#label-considerations-for-choosing-clustering

* 平均クラスタリング深度が大きい場合

平均クラスタリング深度(Clustering Average Depth)とは?

* どの程度マイクロパーティションが
 オーバーラップ(一部の範囲のみ重なる)しているかを図る指標
 => 理想的なマイクロパーティション状態としては、
  他のマイクロパーティションとオーバーラップしていない状態が良い
 => 1以上の数値で、この値が大きいほど理想状態から離れていることになる
 => 詳細は、以下の関連記事を参照のこと

https://dk521123.hatenablog.com/entry/2023/09/20/002235

SYSTEM$CLUSTERING_INFORMATION
https://docs.snowflake.com/ja/sql-reference/functions/system_clustering_information

* テーブルの平均クラスタリング深度を
 含むクラスタリング情報を返す

どういった列をクラスタリングキーとして指定する?

[1] SQLでWHEREになり易い列
 => 例えば、1ヶ月間の請求日
 「WHERE invoice_date BETWEEN '2023-01-01' AND '2023-01-31'」
 で絞るなどをよく行うテーブルに関しては、
 その列をクラスタリングキーとして指定する

[2] (追加のクラスタキーの余地がある場合)結合述語で頻繁に使用される列
 => 例えば、「・・・FROM t1 JOIN t2 ON t1.id = t2.user_id」
  だと、「id」「user_id」をクラスタリングキーとして指定する

4)クラスタリングキーの操作

クラスタリングキーの確認

 「SHOW TABLES;」で
「cluster_by (テーブルのクラスタリングキーとして定義された列)」
を確認する

https://docs.snowflake.com/ja/sql-reference/sql/show-tables#output

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

-- CLUSTER BY ( <expr> [ , <expr> , ... ]) で定義する
CREATE TABLE sample_table (
  date timestamp,
  id varchar(10),
  name varchar(10)
) CLUSTER BY (date, id); -- ★ここ★

-- 確認
show tables like 'sample_table';

ALTER TABLE

-- [1] 変更: CLUSTER BY ( expr [ , expr , ... ] )
ALTER TABLE sample_table CLUSTER BY (date, id);

-- [2] 一時停止: SUSPEND RECLUSTER
ALTER TABLE sample_table SUSPEND RECLUSTER;

-- [3] 再開: RESUME RECLUSTER
ALTER TABLE sample_table RESUME RECLUSTER;

-- [4] 削除: DROP CLUSTERING KEY
ALTER TABLE sample_table DROP CLUSTERING KEY;

5)自動クラスタリング

* クラスタリングキーのメンテナンスは、
 自動クラスタリングをONにしておくと、自動で実施される
 => 「AUTOMATIC_CLUSTERING」として課金

https://docs.snowflake.com/ja/user-guide/tables-auto-reclustering

補足:手動再クラスタリング(非推奨)

* 手動でもできるらしいが、非推奨
 => 詳細は、以下の公式ドキュメントを参照

https://docs.snowflake.com/ja/user-guide/tables-clustering-manual

自動クラスタリングON/OFFの確認

* 「SHOW TABLES;」で「automatic_clustering」で「ON/OFF」を確認する

https://docs.snowflake.com/ja/sql-reference/sql/show-tables#output

自動クラスタリング を有効にする
https://docs.snowflake.com/ja/user-guide/tables-auto-reclustering#enabling-automatic-clustering-for-a-table

より抜粋
~~~~~~~~~~~~~~~
多くの場合、テーブルの自動クラスタリングを有効にするためのタスクは必要ありません。
テーブルに クラスタリングキー を定義するだけです。
~~~~~~~~~~~~~~~
 => 『テーブルに クラスタリングキー を定義するだけ』で
  デフォルトで自動クラスタリングが有効になる

自動クラスタリングの一時停止

-- ALTER TABLE 文の「SUSPEND RECLUSTER」句を指定
ALTER TABLE sample_table SUSPEND RECLUSTER;

https://docs.snowflake.com/ja/user-guide/tables-auto-reclustering#suspending-automatic-clustering-for-a-table

自動クラスタリングの再開

-- ALTER TABLE 文の「RESUME RECLUSTER」句を指定
ALTER TABLE sample_table RESUME RECLUSTER;

https://docs.snowflake.com/ja/user-guide/tables-auto-reclustering#resuming-automatic-clustering-for-a-table

参考文献

https://dev.classmethod.jp/articles/snowflake-advent-calendar-2019-18-micropartition-and-dataclustering/
https://zenn.dev/ryotas_data/articles/a709dadb4717d4
マイクロパーティション
https://zenn.dev/holywater044/articles/972876054c75bc
https://zenn.dev/aaizawa/articles/18663675a5b188
クラスタリング
https://www.intage-ts.com/entry/2020/12/22/124000
https://qiita.com/manabian/items/499b5d51bdfd8ffb36b3
https://dev.classmethod.jp/articles/20220207-snowflake-clustering/

関連記事

Snowflake ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2021/11/02/130111
Snowflake ~ 入門編 / Hello world
https://dk521123.hatenablog.com/entry/2021/11/22/212520
Snowflakeのパフォーマンス改善 ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2023/09/20/002235
Snowflakeのパフォーマンス改善 ~ データロードの改善 ~
https://dk521123.hatenablog.com/entry/2022/12/07/111847
Snowflakeのパフォーマンス改善 ~ 検索最適化サービス ~
https://dk521123.hatenablog.com/entry/2023/02/27/120943