Snowflake を使っていると、
「キャッシュが効いているのにクエリが遅い」
という puzzling な状況に出会うことがあります。
先日、私もまさにそのケースに遭遇しました。
結論から言うと、原因は キャッシュではなく Pruning不発によるフルスキャン でした。
同じような問題で悩んでいる方の参考になればと思い、
今回の内容をまとめておきます。
ちなみにSnowpro Core本番でも、クエリプロファイルの問題は3問ほど出ました。
💡 遭遇した現象(再現イメージ)
数億行規模のテーブルに対してシンプルなクエリを実行したところ、
「こんなに遅い?」というほど時間がかかりました。
クエリプロファイルを開くと、キャッシュヒット率は非常に高い一方で、
パーティションスキャン数が異常に多い ことに気づきました。
以下は、構成をぼかした再現イメージです。
一見、キャッシュ 98% なら速そうなのに、
実際は フルスキャン(2400/2400) が発生しており、
Snowflake 側からも Unselective filter の警告が出ていました。
🔍 何が起きていたのか?
1. キャッシュが効いていても “CPU処理” は減らない
Snowflake のキャッシュは I/O を減らす仕組みであり、
読み込むデータ量そのものを減らすわけではありません。
つまり、
不要なデータまでメモリ上に読み込んでしまえば
CPUでスキャン&集計する時間は変わらず、結果は遅いままです。
2. フルスキャンになっていた
クエリが 2400 個すべてのマイクロパーティションを読む必要がある、
という判断になっていました。
これは明確に Pruningが機能していない状態 です。
Snowflake の高速化の肝は
「読まなくていいパーティションは読まない」
という Pruning にあります。
ここが効かないと、キャッシュが効いているかどうかは関係なく遅くなります。
🛠 解決策:Pruning を効かせるためには?
以下は今回に限らず、SnowflakeでPruningを最大限効かせるための一般的なチェックポイントです。
✔ ① WHERE句でカラムに関数を使わない
Bad(Pruningが効きづらい)
WHERE TO_CHAR(event_timestamp, 'YYYY-MM-DD') = '2024-12-01'
Good(メタデータを活用できる)
WHERE event_timestamp >= '2024-12-01 00:00:00'
AND event_timestamp < '2024-12-02 00:00:00'
MIN/MAX メタデータを Snowflake が利用できるように、
カラムを加工せずそのまま使うのが鉄則 です。
✔ ② データのクラスタリング状況を確認する
もし WHERE user_id = 'A123' のように特定の値で絞っているのに
フルスキャンになる場合は、データの配置がバラバラになっている可能性があります。
以下の関数が有効です:
SELECT SYSTEM$CLUSTERING_INFORMATION('TABLE_NAME');
必要に応じて:
CLUSTER BY の設定
Automatic Clustering の有効化
Search Optimization Service の導入
…などを検討します。
🎯 まとめ
キャッシュヒット率ではなく、Partitions scanned を見るべき
→ ここが total と同じならフルスキャン=遅い
Unselective filter は要注意
→ SQLの書き方か、クラスタリングの問題
Pruning が効くかどうかで Snowflake の性能は激変する
Snowflakeを使ったパフォーマンス改善では、
つい「キャッシュ」に目がいきがちですが、
本当に見るべきは Pruning × スキャン範囲 だと改めて実感しました。
コメント歓迎!
同様の事象に遭遇した方、
Query Profile の読み方で迷っている方、
ぜひ気軽にコメントください 🙌
参考リンク
Pruning の公式説明
https://docs.snowflake.com/en/user-guide/tables-clustering-micropartitions#pruning
