Upgrade to Pro — share decks privately, control downloads, hide ads and more …

【DWH】Snowflakeのクラスタリングキーについて

Avatar for Shin Shin
February 04, 2026
2

 【DWH】Snowflakeのクラスタリングキーについて

Avatar for Shin

Shin

February 04, 2026
Tweet

More Decks by Shin

Transcript

  1. 目次 1. はじめに 2. Snowflakeにおける最適化の前提 3. クラスタリングキーとは何か 4. クラスタリングキーとインデックスとの違い 5.

    効果が出る条件・出ない条件 6. クラスタリングキーと物理配置の関係 7. 検証 8. 実務でどう使うか 9. まとめ
  2. 1.はじめに Snowflake では クラスタリングキーを指定すれば速くなる と思われがち。 しかし実務では • 効果が分からない • すぐに変化しない

    • 期待したほど速くならない ことが多い これは 使い方が間違っているのではなく、 役割の理解がずれている ため。 本スライドでは クラスタリングキーの正体と、 Snowflake における正しい最適化の考え方 を整理する。
  3. 2.SnowFlakeにおける最適化の前提 • Snowflake は 行単位でデータを探さない • データは micro-partition 単位で読み込まれる •

    最適化の中心は 「速く探す」ではなく「読まないデータを増やす 」こと • 不要な micro-partition は MIN / MAX などのメタデータにより事前に除外される • 実行時間やコストは 読んだデータ量(Partitions / Bytes)に強く依存する
  4. 3.クラスタリングキーとは何か • クラスタリングキーは データの並び方に関する「 方針」を指定する仕組み • 指定した列の値が 近い micro-partition に集まりやすくなる

    • インデックスではない ◦ 行を高速に検索する仕組みではない ◦ 指定直後に効果が出るものではない • Snowflake が 物理配置を自動調整するためのヒント として扱う • 目的は プルーニングが効きやすい状態を維持すること
  5. 4.クラスタリングキーとインデックスの違い 観点 クラスタリングキー( Snowflake) インデックス( PostgreSQL など) 目的 データの物理配置を整えやすくする 行に高速に到達する

    対象単位 micro-partition 行(タプル) 即効性 なし(徐々に効く) あり(作成直後から) 効果の出方 プルーニングが効きやすくなる 検索・結合が直接速くなる 指定の意味 配置に関する方針 検索用のデータ構造 管理主体 Snowflake が自動管理 利用者が設計・管理 期待値 将来のスキャン量削減 即時の実行時間短縮
  6. 5.効果が出る条件・出ない条件 • クラスタリングキーは 即座にデータを並べ替える仕組みではない • 指定しても 既存データの配置はすぐには変わらない • Snowflake は

    常に並び替えを行うわけではない • INSERT や UPDATE により データの並びは時間とともに崩れる • クラスタリングキーは 命令ではなく方針 として扱われる • 効果が出るかどうかは データ量・増え方・クエリ条件に依存する
  7. 6.クラスタリングキーと物理配置の関係 • クラスタリングキーと物理配置の関係 ◦ Snowflake は micro-partition 単位でデータを読み込む ◦ 各

    micro-partition には 列ごとの MIN / MAX などのメタデータ がある ◦ 値が物理的にまとまっているほど 不要な micro-partition を除外しやすくなる ◦ クラスタリングキーは この“まとまり”を維持しやすくするための仕組み ◦ 物理配置が整っていると プルーニングが効き、読む量が減る ◦ 物理配置が崩れていると クラスタリングキーを指定しても効果は出にくい
  8. 6.クラスタリングキーと物理配置の関係 • 再配置(再クラスタリング)とは ◦ Snowflake では データは基本的に追加順で物理配置される ◦ クラスタリングキーが指定されている場合、 必要に応じてバックグラウンドで再配置

    が行われる ◦ 再配置は Snowflake 側の判断で実行される ▪ 常時行われるわけではない ▪ 即時に実行されるわけでもない ◦ 再配置の目的は 物理配置の乱れを抑え、 プルーニングが効きやすい状態を維持すること ◦ 再配置には クレジット消費が発生する (必要時のみ。テーブル、変更頻度に依存)
  9. 7.検証 • 検証の目的(クラスタリングキー・再定義) ◦ クラスタリングキーが 実際に適用された場合 と 指定していない場合 で、 以下にどの程度差が出るかを確認する

    ▪ プルーニング効率 ▪ スキャン量 • 検証の前提条件 ◦ 使用する SQL は同一 ◦ 使用するデータは同一 (件数・値の分布は完全に同じ) ◦ Warehouse サイズは同一 違うのは物理配置のみ 👉 差が出た場合、 クラスタリングキー適用による 物理配置の変化 が原因と説明できる
  10. 7.検証 • クラスタリングキーに関する前提 ◦ クラスタリングキーは 物理配置を制御する命令ではない ◦ Snowflake が必要と判断した場合、 再配置(再クラスタリング)が行われる

    ◦ 再配置が行われた場合、 プルーニング効率に直接影響する ◦ 今回は クラスタリングキーが実際に適用されたケース を扱う • 検証に使用するデータ ◦ 行数:約 300 万行 ◦ micro-partition 数:16 ◦ データサイズ:数 MB 程度 ◦ 列構成: ▪ クラスタリングキーに指定する列(category:26 種類) ▪ 日付列(created_at) ▪ ペイロード列(文字列)
  11. 7.検証 • 検証用テーブル構成 ◦ クラスタリングキーなし ▪ T_RANDOM ▪ ランダム順で作成 ▪

    同じ値が全体に散らばる ▪ プルーニングが効きにくい状態 ◦ クラスタリングキーあり ▪ T_RANDOM_CLUSTERED ▪ ランダム順で作成 ▪ クラスタリングキー(category)を設定 ▪ クラスタリングキーの影響で再配置が行われ、 同じ値が近くに集まった状態
  12. 7.検証 • ①使用するクエリ(等価条件) ◦ SELECT COUNT(*) FROM T_RANDOM WHERE category

    = 'A'; ◦ SELECT COUNT(*) FROM T_RANDOM_CLUSTERED WHERE category = 'A'; ▪ 等価条件(=)を使用 ▪ 返却行数の影響を避けるため COUNT(*) ▪ キャッシュの影響を避けて実行 • ②使用するクエリ( IN句) ◦ SELECT COUNT(*) FROM T_RANDOM WHERE category IN ('A','B','C','D','E'); ◦ SELECT COUNT(*) FROM T_RANDOM_CLUSTERED WHERE category IN ('A','B','C','D','E'); ▪ 等価条件の 複数値指定(IN) ▪ 対象データ範囲を意図的に拡張 ▪ プルーニング効率の変化を確認 ▪ キャッシュの影響を避けて実行
  13. 7.検証 ①等価条件 SELECT COUNT(*) FROM T_RANDOM WHERE category = 'A';

    SELECT COUNT(*) FROM T_RANDOM_CLUSTERED WHERE category = 'A'; Percentage scanned from cache スキャン時に参照したデータが キャッシュ( Snowflake内部ストレージ) 上に存在していた割合
  14. 7.検証 • 検証結果の比較(等価条件) ◦ クラスタリングキーなし( T_RANDOM) ▪ Partitions scanned:16 /

    16 ▪ Bytes scanned:1.76 MB ▪ Query insights:特になし ▪ すべての micro-partition をスキャン ▪ 等価条件でも プルーニングがほぼ効いていない ◦ クラスタリングキーあり( T_RANDOM_CLUSTERED) ▪ Partitions scanned:2 / 3 ▪ Bytes scanned:0.67 MB ▪ Query insights:Filter with clustering key ▪ 条件に合致する partition のみをスキャン ▪ プルーニングが有効に機能 • 結果から分かること ◦ SQL・データ内容・件数が同じでも 物理配置の違い によって スキャン対象が大きく変わる ◦ クラスタリングキーが適用されることで、 ▪ 同じ値が近くの micro-partition に集約 ▪ 不要な partition を読み飛ばせる ◦ 結果として、 ▪ Partitions scanned が大幅に減少 ▪ Bytes scanned も削減
  15. 7.検証 ②IN句 SELECT COUNT(*) FROM T_RANDOM WHERE category IN ('A','B','C','D','E');

    SELECT COUNT(*) FROM T_RANDOM_CLUSTERED WHERE category IN ('A','B','C','D','E');
  16. 7.検証 • 検証結果の比較(IN句) ◦ クラスタリングキーなし( T_RANDOM) ▪ Partitions scanned:16 /

    16 ▪ Bytes scanned:1.76 MB ▪ Query insights:特になし ▪ IN 句で対象範囲を広げても 全 micro-partition をスキャン ▪ 値が全体に散らばっているため プルーニングが機能しない ◦ クラスタリングキーあり( T_RANDOM_CLUSTERED) ▪ Partitions scanned:2 / 3 ▪ Bytes scanned:0.67 MB ▪ Query insights:Filter with clustering key ▪ IN 句(複数値)でも 必要な partition のみをスキャン ▪ クラスタリングキーにより 対象値が近い partition に集約 • 結果から分かること ◦ 等価条件が 単一値でも複数値(IN)でも、 クラスタリングキーが適用されていればプルーニングは有効に働く ◦ 条件を広げても、読む partition 数は ほぼ増えていない ◦ 物理配置が整っていれば、 IN 句でも スキャン量は抑えられる
  17. 8.実務でどう使うか ① クラスタリングキーを使うべき場面 • 等価条件 / IN 条件が頻繁に使われる • データ量が多く、増加が見込まれる

    • Query Profile で Partitions / Bytes が多い 👉 「遅い」より「読みすぎている」クエリを確認する ② キー選定の考え方 • WHERE 句でよく使われる列 • 値がある程度まとまる列 • カテゴリ・日付・ID 系など 👉 並びたい列ではなく絞り込みに使われる列
  18. 8.実務でどう使うか ③ 効果確認の方法 • 実行時間では判断しない • 以下を比較する ◦ Partitions scanned

    ◦ Bytes scanned ◦ Query insights • 効果がなければ 無理に使わない ④ 使わない判断も設計の一部 • データ量が小さい • 条件が多様で固定されない • 再配置コストが見合わない 👉 クラスタリングキーは万能ではない
  19. 9.まとめ • Snowflake では 実行時間よりも「どれだけ読んだか」 が重要。 • 同じ SQL・同じデータでも、 物理配置の違い

    によって スキャン量(Partitions / Bytes)は大きく変わる。 • クラスタリングキーが適用されると、 プルーニング効率が向上し、 読むデータ量を削減できる。 • 等価条件・IN 条件でも、 配置が整っていれば効果は維持される。 • 実務では 「遅い」クエリではなく 「読みすぎている」クエリを確認することが重要。 📌Snowflake の最適化は、  クエリを書くことではなく  データの「置き方」を意識することから始まる。