第4章 パフォーマンス最適化・クエリ・変換(Performance & Transformation, 21%)
🎯 この節の学習目標
Snowflake には性質の異なる3種類のキャッシュがあり、それぞれ存在する層(クラウドサービス層か、ウェアハウスか)と寿命、効く条件が違います。この3つを混同すると、「ウェアハウスを止めたのに結果が即座に返るのはなぜか」「同じクエリなのにキャッシュが効かないのはなぜか」といった動作が説明できません。試験でも3つを区別させる問題が中心なので、本節は比較表まで含めて確実に押さえてください。
クエリ結果キャッシュは、実行したクエリの結果そのものをクラウドサービス層に保存する仕組みです。条件を満たす同一クエリが再度実行されると、Snowflake は計算をやり直さず、保存済みの結果をそのまま返します。
再利用には、主に次の条件をすべて満たす必要があります。
| 条件 | 補足 |
|---|---|
| クエリテキストが実質的に同一 | 空白や大文字小文字の違いでも別クエリと見なされることがある。構文的に同じ結果を返すだけでは不十分 |
| 対象テーブルのデータが変わっていない | INSERT/UPDATE/DELETE などでデータやマイクロパーティションが変化すると無効化される |
| 実行時依存の関数を含まない | CURRENT_TIMESTAMP() や RANDOM() など、実行のたびに値が変わる関数を含むと再利用されない |
| 十分な権限がある | 結果を再利用するユーザーが、対象テーブルへの必要な権限を持っていること |
| USE_CACHED_RESULT が TRUE | 既定は TRUE。FALSE にすると結果キャッシュを使わない |
💡 具体例:性能検証のためにキャッシュを無効化する
-- セッション単位で結果キャッシュを無効化(チューニングの計測時に使う)
ALTER SESSION SET USE_CACHED_RESULT = FALSE;
-- 1回目:ウェアハウスで実行される
SELECT region, SUM(amount) FROM sales GROUP BY region;
-- 2回目:USE_CACHED_RESULT=TRUE なら結果キャッシュから即座に返るが、
-- FALSE にしているため毎回ウェアハウスで実行される
ウェアハウスサイズ変更などの効果を測るときは、結果キャッシュが効くと計測になりません。USE_CACHED_RESULT = FALSE で無効化してから比較するのが定石です。
ウェアハウスキャッシュは、仮想ウェアハウスの各ノードが、クエリ実行時にリモートストレージから読み取ったテーブルデータ(マイクロパーティション)を自身のローカルディスク(SSD)に保持しておく仕組みです。データキャッシュ、ローカルディスクキャッシュとも呼ばれます。
📝 試験のポイント
auto-suspend の設定とのトレードオフが問われます。サスペンドまでの時間を短くするほどアイドル時のクレジット消費は抑えられますが、サスペンドのたびにウェアハウスキャッシュが失われ、再開直後のクエリが遅くなります。断続的にクエリが来る BI 用ウェアハウスなどでは、auto-suspend を極端に短くするとかえって体感性能とコスト効率が悪化することがあります。「コスト節約」と「キャッシュ維持」のバランスとして理解しておきましょう。
Snowflake はクラウドサービス層で、各テーブル・各マイクロパーティションの統計情報(行数、列ごとの最小値・最大値、個別値数など)を常に保持しています。このメタデータだけで答えられるクエリは、ウェアハウスを使わずに応答されることがあります。
-- メタデータだけで応答できることがあるクエリの例
SELECT COUNT(*) FROM sales; -- 行数はメタデータに記録済み
SELECT MIN(order_date), MAX(order_date) FROM sales; -- min/max も記録済み
-- SHOW / DESCRIBE などのメタデータ操作もウェアハウス不要
SHOW TABLES IN SCHEMA analytics.public;
これらはウェアハウスがサスペンド中でも即座に返り、ウェアハウスのクレジットを消費しません。なお、WHERE 句で複雑に絞り込んだ COUNT や、一般の SELECT はメタデータだけでは答えられないため、通常どおりウェアハウスで実行されます。メタデータは 1-6 で学んだパーティションプルーニングにも使われており、「クラウドサービス層が持つ統計」という同じ仕組みの別の顔です。
3つのキャッシュを1枚の表に整理します。この表の内容はそのまま試験の論点です。
| クエリ結果キャッシュ | ウェアハウスキャッシュ | メタデータキャッシュ | |
|---|---|---|---|
| どの層にあるか | クラウドサービス層 | 各ウェアハウスのローカルディスク | クラウドサービス層 |
| 何を保持するか | クエリの結果 | 読み取ったテーブルデータ | 統計情報(行数・min/max など) |
| 寿命 | 24時間(再利用で延長、最大31日)。データ変更で無効化 | ウェアハウス稼働中のみ。サスペンドで消える | 常に最新に維持される(明示的な期限なし) |
| 効く条件 | 同一クエリテキスト+データ不変+権限などの条件を満たす再実行 | 同じウェアハウスで、同じデータ(の一部)を読むクエリ | COUNT(*)・MIN/MAX など統計だけで答えられるクエリ |
| ウェアハウス | 不要(クレジット消費なし) | 必要(稼働中のWHで効く) | 不要(クレジット消費なし) |
| 共有範囲 | ウェアハウス・ユーザーをまたいで再利用可(権限が必要) | そのウェアハウス内のみ | アカウント全体 |
クエリが発行されたとき、Snowflake が概念的にどの順で応答手段を選ぶかをフローで示します。
図:クエリ応答の概念フロー。上の2段はウェアハウスを起動せずに完結する
✅ この節のまとめ
問1. クエリ結果キャッシュに関する説明として正しいものはどれか。
正解:B
結果キャッシュはクラウドサービス層にあり、ヒット時は計算不要なのでウェアハウスなし・クレジット消費なしで返ります。Aはウェアハウスキャッシュの説明です。Cは誤りで、結果キャッシュはウェアハウスに属さないため、サスペンドの影響を受けません。Dは誤りで、元データが変更されるとキャッシュは無効化されます(31日は「再利用され続けた場合の最大延長」です)。
問2. ウェアハウスの auto-suspend を60秒などごく短く設定した場合に起こり得ることとして、最も適切なものはどれか。
正解:C
ローカルディスクキャッシュはウェアハウス稼働中のみ有効なので、頻繁なサスペンドはキャッシュの喪失を繰り返し、再開後の初回クエリ群が遅くなります。A・Bのキャッシュはどちらもクラウドサービス層にあり、ウェアハウスのサスペンドの影響を受けません。Dは誤りで、アイドル課金は減るものの、キャッシュ喪失による性能低下(および実行時間の延び)という代償があり、「必ず得」とは言えません。
問3. ウェアハウスがすべてサスペンドされている状態で、即座に結果が返る可能性のあるクエリはどれか。2つ選べ。
正解:A、C
Aは行数というメタデータだけで応答できる可能性があり、ウェアハウス不要です。Cは結果キャッシュの再利用条件(同一テキスト・データ不変・権限)を満たしており、クラウドサービス層から返せます。Bは実データのスキャンが必要な初回実行なのでウェアハウスの起動(レジューム)が必要です。Dは CURRENT_TIMESTAMP() という実行のたびに値が変わる関数を含むため、結果キャッシュが再利用されません。
問4. ウェアハウスサイズ変更の性能効果を正しく計測するために、事前に行うべき設定はどれか。
正解:A
結果キャッシュが効くと2回目以降の実行は計算そのものをスキップしてしまい、ウェアハウス性能の比較になりません。USE_CACHED_RESULT = FALSE で結果キャッシュを無効化してから計測します。Bのクエリタグは調査用のラベル付けであり、キャッシュ動作には影響しません。Cはレジュームの自動化設定で計測とは無関係です。Dのような「メタデータキャッシュを削除する」構文は存在しません。