費用の話は、合計額だけを見ていても進みません。「先月より2割増えた」から打てる手はなく、誰が・何に・いくら使ったかまで分解して初めて判断できます。
幸い は、その情報を として SQL で参照できる形で持っています。この回はその使い方を扱います。
1. まずウェアハウス別に分解する
最初の一歩は、どのウェアハウスがいくら消費しているかです。EP.2 で用途別に分けていれば、これがそのまま用途別の内訳になります。
SELECT warehouse_name AS ウェアハウス, DATE_TRUNC('day', start_time) AS 日付, ROUND(SUM(credits_used), 2) AS 消費, ROUND(SUM(credits_used_compute), 2) AS うち計算, ROUND(SUM(credits_used_cloud_services), 2) AS うち管理系FROM snowflake.account_usage.warehouse_metering_historyWHERE start_time >= DATEADD(day, -30, CURRENT_TIMESTAMP())GROUP BY 1, 2ORDER BY 日付 DESC, 消費 DESC;これを30日ぶん並べると、傾向と異常の両方が見えます。じわじわ増えているのか、特定の日だけ跳ねているのか。跳ねている日があれば、その日のクエリ履歴を見に行きます。じわじわ増えている場合のほうが厄介で、日々の変化が小さいため誰も気づかず、数か月後に請求で発覚します。合計額だけを月次で見ていると、この形は必ず見落とします。
利用状況ビュー は集計されたビューのため、直近のデータには反映の遅れがあります。「今まさに何が動いているか」を見たい場合は、リアルタイム性の高い別の関数やビューを使う必要があります。用途で使い分けてください。
2. 消費の大きいクエリを特定する
ウェアハウス単位で当たりがついたら、中身を見ます。クエリ履歴には実行時間や読み取り量が記録されています。
ここで注意すべきは、1本の重さではなく合計で見るという点です。EP.2 で扱ったとおり課金は起動時間に紐づくため、短いが大量に走るクエリが総量では上回ることがあります。
-- 値の違いを無視して、同じ形のクエリをまとめて集計するSELECT query_type, warehouse_name AS ウェアハウス, LEFT(REGEXP_REPLACE(query_text, '[0-9]+', 'N'), 80) AS クエリの形, COUNT(*) AS 実行数, ROUND(SUM(total_elapsed_time) / 1000 / 60, 1) AS 合計分, ROUND(AVG(total_elapsed_time) / 1000, 1) AS 平均秒, ROUND(SUM(bytes_scanned) / POWER(1024, 3), 1) AS 読取GBFROM snowflake.account_usage.query_historyWHERE start_time >= DATEADD(day, -7, CURRENT_TIMESTAMP()) AND warehouse_name IS NOT NULLGROUP BY 1, 2, 3ORDER BY 合計分 DESCLIMIT 30;合計分で並べるのが要点です。平均秒で並べると、たまにしか走らない重いクエリが上位に来ますが、それは総量への寄与が小さいかもしれません。実行数 × 平均で効いているものを探します。
この考え方は、パフォーマンスチューニング実践 EP.02 で扱った「回数を数える」と同じです。1回の速さではなく合計で見るという原則は、費用でも性能でも変わりません。
3. 誰が使っているかを見る
組織で使っていると、利用者やロール別の内訳が必要になります。クエリ履歴には実行者とロールが記録されています。
SELECT role_name AS ロール, user_name AS 利用者, COUNT(*) AS 実行数, ROUND(SUM(total_elapsed_time) / 1000 / 60, 1) AS 合計分, ROUND(SUM(bytes_scanned) / POWER(1024, 4), 2) AS 読取TBFROM snowflake.account_usage.query_historyWHERE start_time >= DATEADD(day, -30, CURRENT_TIMESTAMP()) AND warehouse_name IS NOT NULLGROUP BY 1, 2ORDER BY 合計分 DESCLIMIT 30;ここで見えるのは時間と読み取り量であって、金額そのものではありません。金額に換算するには、そのウェアハウスのサイズを掛ける必要があります。厳密な按分より、まず偏りを掴む目的で使うのが実務的です。
利用者別の数字は、個人を責める材料にすると必ず萎縮を招きます。データを触るのをためらう文化ができると、可視化した本来の目的(活用の促進)を損ないます。仕組みで防げないかという視点で使ってください。
4. 保管の費用も見る
計算に目が行きがちですが、保管の費用も積み上がります。特に の保持期間を長く設定していると、変更量に応じて過去の版を保持し続けます。
SELECT table_catalog AS データベース, table_schema AS スキーマ, table_name AS テーブル, ROUND(active_bytes / POWER(1024, 3), 2) AS 現在GB, ROUND(time_travel_bytes / POWER(1024, 3), 2) AS 過去版GB, ROUND(failsafe_bytes / POWER(1024, 3), 2) AS 保険GBFROM snowflake.account_usage.table_storage_metricsWHERE deleted = FALSEORDER BY (active_bytes + time_travel_bytes + failsafe_bytes) DESCLIMIT 20;現在の量より過去の版のほうが大きいテーブルがあれば、それは頻繁に全件を入れ替えている可能性が高い。EP.6 で扱いますが、保持期間はテーブルごとに決められるので、一時的な作業用テーブルまで長く保持する必要はありません。中間テーブルや検証用の複製が、本番と同じ設定のまま放置されているのはよく見る形です。
5. 定点観測にする
一度調べて終わりでは、数か月後に同じ調査をやり直すことになります。定期的に出る形にしておくと、変化に気づけます。
- 1日次でウェアハウス別の消費を記録する — 傾向が見える
- 2週次で上位クエリを出す — 新しく増えた重い処理に気づける
- 3閾値を決めて通知する — 平常時の何倍かを超えたら知らせる
- 4保管量を月次で見る — じわじわ増えるので、たまに見れば足りる
3番目は費用対効果が高い施策です。跳ねたその日に気づけるのと、請求が来てから気づくのとでは、対処できる範囲がまったく違います。とはいえ、これは の一般論と同じで、通知の宛先と対応の担当を決めていないと機能しません。
可視化の仕組みそのものについては エンジニアリング・ダッシュボード EP.07「DWH コスト」 にもまとめてあります。
6. 見えたあと、何から手を付けるか
内訳が出たら、消費の大きい順に扱います。多くの場合、上位のいくつかで全体の大半を占めます。
| 見えたもの | 疑うこと | 扱う回 |
|---|---|---|
| 特定のウェアハウスが常時起動 | 止め方の設定 | EP.4 |
| 読み取り量が異常に多い | 読み飛ばしが効いていない | EP.5 |
| 同じクエリが大量に走る | 結果の使い回しができないか | EP.4 |
| 過去の版が現在より大きい | 保持期間の設定 | EP.6 |
| 調査用途の消費が大きい | サイズと上限の設定 | EP.2 |
合計額からは打ち手が出ない。ウェアハウス別 → クエリの形別 → 利用者別に分解する。並べるのは平均ではなく合計(回数が効く)。保管の費用、特に過去の版の量も見る。そして定点観測と通知にして、請求が来る前に気づける形にする。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。