dbtでデータ基盤を運用し始めた最初の数ヶ月は、Snowflakeのクレジット消費もそこそこに収まります。「これなら年間予算で十分」と思っていたある月末、コストが2倍3倍に跳ねていて経理から問い合わせが来る、というのはよくある光景です。原因は判断ミスの積み重ねです。

dbt + Snowflakeのコスト構造は明瞭で、抑える勘どころも限られます。効くポイントを順に押さえます。

何にお金がかかっているのか

Snowflakeの課金は、おおまかにストレージとコンピュートに分かれます。dbt運用で跳ねるのはコンピュート、つまり仮想ウェアハウスの稼働時間です。仕組みはSnowflakeとはに整理しています。

原因典型症状
materializationの選定ミス大きなテーブルがtable/viewのまま、毎回全件処理
ウェアハウスサイズが過剰軽い処理にLargeを使い続ける
full-refreshの乱用本来incrementalで済むモデルを毎晩作り直す
auto_suspend が長いジョブ終了後も10分以上動き続ける
ジョブの並行衝突BIとETLが同じウェアハウスで取り合い
マートが過剰使われていないGold層のテーブルが毎晩構築される

対策1:materializationを正しく選ぶ

各モデルのmaterialization見直しが最も効果的です。判断軸はシンプルです。

状況推奨
クエリが軽く、参照が少ないview
中規模、追加・更新が複雑table
大規模、追加中心incremental
履歴管理が必要snapshot

大きなファクトテーブルがtableのままになっていないか、まず棚卸しします。incrementalの設計はincremental modelsの設計で詳しく扱っています。

対策2:ウェアハウスをサイズと用途で分ける

1つのウェアハウスで全部をさばくと、用途の違う処理が互いを遅くしてコストも膨らみます。dbt運用なら、最低限こう分けると効きます。

ウェアハウス用途推奨サイズ
WH_DBT_TRANSFORMdbtのrun/test/buildS〜M(負荷次第でscale up)
WH_BIBIツールからの参照XS〜S(同時実行多めならマルチクラスタ)
WH_ADHOC分析者の手動クエリXS〜S
-- 用途別ウェアハウスの最小設定
CREATE WAREHOUSE wh_dbt_transform
  WAREHOUSE_SIZE = 'SMALL'
  AUTO_SUSPEND = 60           -- 60秒アイドルで停止
  AUTO_RESUME = TRUE
  MIN_CLUSTER_COUNT = 1
  MAX_CLUSTER_COUNT = 1;      -- 単一クラスタで十分

対策3:auto_suspendを短く

auto_suspendはアイドル状態のウェアハウスを停止するまでの待ち時間です。既定の10分は、dbt運用には長すぎます。60秒で十分なケースが多いです。

注意点は、ウェアハウスが停止するとキャッシュも失われ、次回起動時に再度コンパイル・データ読み込みが必要になることです。BIで頻繁に参照されるウェアハウスは、auto_suspendを少し長め(300〜600秒)にして、キャッシュ効果を残すと体感速度とコストのバランスが取れます。dbt実行用は60秒、BI参照用は300秒、と用途で分けるのが定石です。

対策4:full-refreshを安易に使わない

CI/CDで`dbt build –full-refresh`を毎晩走らせている、というケースを時々見ます。原因はだいたい「過去データの修正に対応するため」ですが、それなら遅延データ用の窓を入れたincrementalで対応できます。

-- 遅延データ対策:過去3日まで遡って再評価
{% if is_incremental() %}
  WHERE ordered_at >= DATEADD(day, -3, (SELECT MAX(ordered_at) FROM {{ this }}))
{% endif %}

full-refreshが必要なのは、ロジック変更後の初回ビルドと、月1回程度の整合性確認だけにします。日次運用から外すと、それだけでコストが大きく下がります。

対策5:使われていないモデルを止める

Gold層に「念のため」作ったマートが、誰にも使われていないのに毎晩構築されている、というのは現場でよく起こります。Snowflakeの`ACCESS_HISTORY`や`QUERY_HISTORY`から、参照されていないテーブルを洗い出せます。

-- 過去30日間に参照されていないテーブル
SELECT
  table_name,
  MAX(query_start_time) AS last_used
FROM snowflake.account_usage.access_history,
  LATERAL FLATTEN(direct_objects_accessed)
WHERE query_start_time >= DATEADD(day, -30, CURRENT_TIMESTAMP())
  AND value:objectDomain = 'Table'
GROUP BY table_name
HAVING MAX(query_start_time) IS NULL
ORDER BY last_used;

洗い出したモデルは、`enabled: false`で一時的に止めるか、削除します。dbtのexposuresを書いていれば「BIが参照しているか」も追跡できるので、判断が安全になります。

対策6:dbtのクエリにタグを付けて可視化する

どのモデルがどれだけクレジットを消費しているか、を可視化するとボトルネックが一目で分かります。dbtの`+query_tag`を使うと、Snowflakeのクエリ履歴にタグを付与できます。

-- dbt_project.yml
models:
  my_project:
    silver:
      +query_tag: "{{ 'dbt_silver_' ~ this.identifier }}"
    gold:
      +query_tag: "{{ 'dbt_gold_' ~ this.identifier }}"

これでSnowflakeのクエリ履歴に`dbt_silver_fct_orders`のようなタグが付き、`query_history`をクエリすればモデル別にクレジット消費を集計できます。「重いトップ10」が見えるだけで、改善の優先順位が決まります。

まとめ

  • 大きなファクトをtableのままにしない。incrementalに切り替える。
  • ウェアハウスは用途で分け、サイズは控えめから始めて必要時にscale upする。
  • auto_suspendは60秒を基本に、BI参照用だけ長めにする。
  • full-refreshを日次から外し、遅延データは増分の窓で吸収する。
  • 参照されていないGoldマートを止める。query_tagで重いトップ10を可視化する。

関連:dbt incremental modelsの設計dbt tests 実践dbt snapshotsでSCD Type 2。Snowflake全般の設計はSnowflakeとは、クラウドDWH選定はクラウドDWH入門もあわせてどうぞ。コストレビューや改善の壁打ちは、DE-STKの初回相談(30分・無料)もご利用ください。

よくある質問(FAQ)

Q. ウェアハウスを小さくしすぎると、ジョブが終わらないのでは?

A. 小さすぎると確かに終わらなくなりますが、まず計測してから調整するのが正解です。XSやSで動かしてみて、許容できる時間内に終わるなら、それで十分です。クレジット消費はサイズと時間の積なので、「Lで30分」と「Sで60分」が同じ金額のケースもあります。終わらない処理だけサイズを上げる、という調整が現実的です。

Q. クエリのタグ付けは、後からでも入れられますか?

A. 入れられます。`dbt_project.yml`に`+query_tag`を足してデプロイすれば、次の実行から効きます。既存の運用を止めずに導入できる施策なので、まず最初に入れるとよいです。タグ付けされたデータが1週間ほど溜まれば、重いトップ10が見えてきます。

Q. BIツールがSnowflakeに直接クエリを投げると、コストが膨らみませんか?

A. BIの利用頻度次第ですが、対策はあります。事前集計したワイドテーブルをGold層に用意し、BIはそれだけを参照する。BI専用のウェアハウスを分けて、auto_suspendを短く、サイズを控えめにする。LookerのPersistent Derived Tablesのようなキャッシュ機構を活用する。これらで、利用が増えてもコストの線形増を抑えられます。

Q. クレジット消費が急に増えました。どこから調べますか?

A. まず`account_usage.warehouse_metering_history`で、どのウェアハウスが消費しているかを切り分けます。次に、そのウェアハウスの`query_history`から長時間・高コストのクエリを特定します。「最近追加された大きいモデルがfull-refreshされている」「BIの新ダッシュボードが重い」「auto_suspendが解除された」あたりが定番の原因です。改善の効果は数日で見えるので、計測しながら一つずつ潰します。

▼ このトピックをポチポチ学ぶ

dbtを深く使いこなす

関連記事を順序立てて読みながら、ステップごとに4択クイズで理解を確認できる学習パスです。登録不要・進捗自動保存。

学習パスを始める →