
Snowflakeのキャッシュについてまとめてみる
AkimasaKajitaniです。
今回は、Snowflakeが持っているキャッシュについて理解を深めるために少しまとめてみたいと思います。
Snowflakeのキャッシュ
データウェアハウスの速度アップおよび負荷軽減のために、キャッシュという技術を利用することができますが、Snowflakeでもキャッシュが導入されています。
Snowflakeでは、キャッシュは主に3つです。
- クエリ履歴キャッシュ(Query Result Cache)
- ウェアハウスキャッシュ(Warehouse Cache)
- メタデータキャッシュ
Snowflakeは様々なメタデータをクラウドレイヤーに保存しており、例えばレコードのカウントなどはメタデータからすぐに入手することが可能です。つまり以下のようなSQLを書いた場合は、メタデータから答えが帰ってきます。
SELECT COUNT(*) FROM Tablename;
クエリした内容がメタデータではなかった場合、つぎに効いてくるキャッシュはクエリ履歴キャッシュで、これにヒットすればウェアハウスは起動しません。つまりコスト効率UPということになります。一方で、ウェアハウスキャッシュは、クエリの実行時にウェアハウスのSSDにコピーされているデータのことで、ウェアハウスが停止するとクリアされます。
この3つのキャッシュを表にまとめてみました。
項目 | メタデータキャッシュ | クエリ履歴キャッシュ | ウェアハウスキャッシュ |
---|---|---|---|
クリアタイミング | なし(永続的) | タイマーもしくは元のデータが更新されたとき | ウェハウスが停止もしくは元のデータが更新されたとき |
タイマー | なし(永続的) | ・クエリごとに24時間(問い合わせがあればタイマーは0に戻る)
・31日で削除 |
なし |
参考URL
ざっくりとSnowflakeのキャッシュについてわかりやすく解説しています。
それぞれのキャッシュについてさらに深堀りしてみましょう。
メタデータキャッシュについて
Snowflakeはデータがロードされたタイミングで、列志向形式のデータとして保存しますが、このときメタデータも保存しています。メタデータは例えば最大値、最小値、レコードカウントなどが該当します。そのため、これらの保存されたメタデータを問い合わせるようなSQLの場合は、ウェアハウスが動作せず、この保存されたメタデータをそのまま返します。これがメタデータキャッシュです。
※参考URL:重要な概念およびアーキテクチャ
キャッシュが効いているかどうか確認する
キャッシュが効いているかどうかは、クエリ結果から判別可能です。Snowsight(WEB画面)の「モニタリング」の「クエリ履歴」から確認することができます(他の方法もあります)。各クエリのクエリプロファイルを開くと、メタデータキャッシュにあたった場合は以下のように表示されます。
「METADATA-BASED RESULT」がメタデータキャッシュのことです。
ところで、通常、
SELECT COUNT(*) FROM Tablename;
といったSQLは、データベースマネジメントシステムによっては、結果が遅いものがあるので推奨されない書き方ですが、Snowflakeの場合はメタデータキャッシュのおかげでまったく気になりません。
クエリ履歴キャッシュについて
クエリ履歴キャッシュは、ウェアハウスが起動しない非常に経済的なキャッシュですが、色々と条件もあります。SQLが大文字、小文字含めて全く同じである、ということと、結果が固定的であるということなどが代表的な制限です。
制限事項
- SQL文は大文字、小文字含めて全く同じである必要がある
- キャッシュが効かない関数に注意
- UUID_STRING、RANDOM、RANDSTR等
- 外部関数が含まれていないこと
- ハイブリッドテーブルに対するSELECTではないこと
- アクセス権限があること
その他
- USE_CACHED_RESULT パラメーターでキャッシュの利用のオン・オフができる
ベンチマークを行う場合などは、キャッシュオフでテストする、ということも可能です。
キャッシュが効いているかどうか確認する
キャッシュが効いているかどうかは、クエリ結果から判別可能です。Snowsight(WEB画面)の「モニタリング」の「クエリ履歴」から確認することができます(他の方法もあります)。各クエリのクエリプロファイルを開くと、キャッシュが効いていない場合は以下のように表示されます。
一方で、キャッシュが効いている場合は以下のように表示されます。
「QUERY RESULT REUSE」というのが履歴にヒットした、ということです。
参考URL
ウェアハウスキャッシュについて
ウェアハウスキャッシュは、クエリ実行時にウェアハウスのSSDにコピーされているデータをキャッシュとして利用できる機能です。クエリ実行時に、ストレージからウェアハウスにデータがコピーされるようになっていますが、この処理がない分早くなる、ということになります。
もう少し詳しく解説すると、
Remote Disk IO ⇒ Local Disk IOの後、Processingされる、とあります。実際のウェアハウスキャッシュにヒットしていない場合は、以下のようにクエリ履歴で表示されます。
確かに「リモートディスクI/O」と書かれています。
このLocal Disk IOというのがウェアハウスのストレージということになります。
例えば、このウェアハウスキャッシュにヒットしていると、
といった形で「リモートディスクI/O」の文字が出てきません。
なお、このキャッシュはウェアハウスが停止するとクリアされるようになっているため、ウェアハウスが起動しっぱなしである方がキャッシュにあたりやすい、ということになります。似たようなデータをクエリするような場合は有効活用されるはずです。
それでは、どれくらいキャッシュされているデータがあるのでしょうか?以下のドキュメントではそのSQLが公開されています。
以下のSQLは上記のドキュメントに記載されていますが、そのまま実行可能なSQLです(ACCOUNTADMINの権限が必要です)。このSQLは、snowflakeDBを見に行っており、過去のSQL履歴からどれくらいキャッシュが使われているか、というのを見るためのSQLです。
SELECT warehouse_name
,COUNT(*) AS query_count
,SUM(bytes_scanned) AS bytes_scanned
,SUM(bytes_scanned*percentage_scanned_from_cache) AS bytes_scanned_from_cache
,SUM(bytes_scanned*percentage_scanned_from_cache) / SUM(bytes_scanned) AS percent_scanned_from_cache
FROM snowflake.account_usage.query_history
WHERE start_time >= dateadd(month,-1,current_timestamp())
AND bytes_scanned > 0
GROUP BY 1
ORDER BY 5;
この結果は以下の通りとなります。
ガイドラインもドキュメントに記載されています。(自動停止についてのガイドライン )
BIなどではキャッシュが重要なため10分程度。データサイエンス系はキャッシュはそれほど重要ではないため5分、とされています。とはいえ、起動時間はコストに直結する部分ですので、利用がそもそも少なくて10分間ユーザーがアクセスしないことが多い、というレベルであればこのガイドラインの通りにする必要はないですし、ある程度利用が多く、パフォーマンス的に気になる、ということであれば、見直しても良いかもしれません。とはいえ、利用が増えればそれだけウェアハウスが自動停止しなくなるのでキャッシュが活きてくる、ということになると思います。
どれだけのデータをキャッシュできますか?
この質問に対しては、ローカルストレージのサイズが公表されていないので不明です。
参考URL
※2025年7月7日時点の情報です