Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Snowflakeのコスト最適化を支えるアーキテクチャ設計

 Snowflakeのコスト最適化を支えるアーキテクチャ設計

Snowflakeのコスト最適化を、設定やSQLチューニングだけでなく、アーキテクチャ設計の観点から整理します。Icebergを活用した不要なデータ取り込みの削減、要件に応じた取り込み方式の選択、データ共有によるコピーの削減、ウェアハウスの集約と分離の判断を、実践例を交えて紹介します。

Avatar for Tatsuya Koreeda

Tatsuya Koreeda

September 11, 2026

More Decks by Tatsuya Koreeda

Other Decks in Technology

Transcript

  1. 自己紹介 名前 是枝 達也 / Tatsuya Koreeda 略歴 株式会社 GA

    technologies, Data本部 Data Managementチーフ 肩書き・活動 ・Snowflake Data Superhero 2026 ・Snowflake UG リーダー( WEST / HCLS) 趣味 バイオインフォマティクス研究 Snowflakeで好きな機能 Snowpark Container Service
  2. コスト最適化する仮想のデータ基盤アーキテクチャ 運用状況 ワークロードはパフォーマンスよりも コスト最適に振りたい RAW/STG/MARTのwarehouseは サイズMで処理している。マルチクラ スターも使用 部署ごとにwarehouseを区切ってい る データソースの取り込み、

    Snowflakeデータ更新は毎次更新 Snowflake → データソース 毎次更新 毎次更新 ETL / ELT RAW table → 毎次更新 STG → 毎次更新 table MART table 他のingest先 (Data Lakeなど) Snowflake以外にも、他部署では別 のDWHを使っている BIツールなどでビジネス指標を運用 する 今回、こちらのデータ基盤アーキテクチャをコスト最適化させていきます ← BI / 分析
  3. 大部分のコストは warehouseが占めている ほとんどの場合、warehouseのコストが一番大きい。 コスト最適化はwarehouseの最適化と言っ ても過言ではない。 SERVICE TYPE別 credit比率 + ストレージ

    WAREHOUSE_METERING 約70〜90% STORAGE 約5〜15% SERVERLESS_TASK 約5〜10% COMPUTES / PIPE 約1〜5% AI_FUNCTIONS / AI_INFERENCE その他 ※ あくまで目安です。 約1〜5% 約1〜5%
  4. warehouseでやらないほうがよい例 1:外部APIへリクエスト -- ダメな例:warehouse-backed TaskがAPI呼び出しの完了を待 ち続ける CREATE OR REPLACE TASK

    call_external_api_task WAREHOUSE = my_wh SCHEDULE = '5 MINUTE' AS CALL call_api_and_wait_sp(); -- SP内でrequests的な UDF/外部関数を呼び、応答をポーリング 外部APIの応答待ちも、warehouseは動き続ける 外部APIのレスポンス待ち =warehouse課金し続けるだけの時間 実処理 APIレスポンス待ち(課金される)
  5. warehouseでやらないほうがよい例 2:StreamlitのWarehouse Runtime -- ダメな例:StreamlitアプリをWarehouse Runtimeで作成 CREATE STREAMLIT my_app MAIN_FILE

    = 'streamlit_app.py' QUERY_WAREHOUSE = my_wh; -- ランタイム指定なし → 既定でWarehouse Runtime -- セッション中はUI操作の有無にかかわらずwarehouseが起 動し続ける Streamlit in SnowflakeのWarehouse Runtime は、アプ リ の描画・ UI制御もwarehouse上で動く。 ユーザーが画面を見ているだけでクエリを発行していなくても、 warehouseは起動したまま になりやすい。 Container Runtimeを選べば、アプリの実行を SPCS上のcomputeに切り離せる
  6. API呼び出しは SPCS Job / container runtimeへ SPCS Jobとして実行する EXECUTE JOB

    SERVICE IN COMPUTE POOL my_cpu_pool NAME = api_batch_job ASYNC = TRUE FROM SPECIFICATION $$ spec: containers: - name: main image: /db/schema/repo/api-caller:latest env: TARGET_TABLE: RAW.API_RESULTS $$; ASYNC  TRUEで非同期処理に切り出し 。warehouseはJob起動のトリ ガーだけ。 Notebookのcontainer runtimeで動かす # Notebook実行環境を Container Runtime に設定 # (UI: Runtime > Container Runtime を選択) import requests, snowflake.snowpark as sp session = sp.context.get_active_session() resp = requests.get("https://api.example.com/data") df = session.create_dataframe(resp.json()) df.write.save_as_table("RAW.API_RESULTS") warehouse-backed Notebookではなく、 Container Runtimeを選べば SPCS上のcomputeで実行される。 どちらも warehouseを起動・待機させない点が共通。 API呼び出しや Python中心の処理は、最初からこちら側に置く。
  7. warehouseを分けずに query_tagで分ける 1. ユーザーにタグを付ける ALTER USER taro_yamada SET QUERY_TAG =

    'COST_CENTER=finance'; warehouse分ける理由になるもの SLA / ワークロード干渉 warehouse分けなくてもできること 誰が何を実行したかの管理は query_tag で足りる 2. タグ別にクレジットを集計する SELECT COALESCE(NULLIF(query_tag, ''), 'untagged') AS tag, SUM(credits_attributed_compute) AS compute_credits, SUM(credits_used_query_acceleration) AS qas FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY WHERE start_time >= DATEADD(MONTH, -1, CURRENT_DATE) GROUP BY tag ORDER BY compute_credits DESC; 出典:Snowflake Documentation「コスト帰属」 docs.snowflake.com/ja/user-guide/cost-attributing
  8. AUTO_SUSPENDの設定値 ワークロード 結論 A|1分以上のクエリ 短い値が有利 。実行時間が60秒を超えるので、待機ぶんがそのま ま無駄になる。 B|数秒のクエリが数秒間隔 長めの値が有利 。短くすると起動が分かれ、最低60秒課金を何度

    も踏む。 C|実行時間・間隔が様々 勘では決まらない 。設定値で起動回数が変わるので、クエリ履歴か らシミュレーションして決める。 出典:井上樹「このSnowflakeウェアハウスの自動停止時間は何秒が最適なのか?クエリ履歴から算出するコスト最小化検証実験(超節約生活実験)」NTT DATA TECH (Zenn), 2025年12月1日 https://zenn.dev/nttdata_tech/articles/9df82505179e8a(著者の方に掲載許諾を取得済み)
  9. マルチクラスターウェアハウスの scaling policy SCALING_POLICY クラスターを起動する条件 シャットダウンする条件 向いているワークロード Standard クエリがqueueした /

    現在のクラス ターでは捌けないと判断した時点で すぐ起動 負荷の低い状態が続いたら、最も空 いているクラスターから停止 待たせたくないクエリ 追加クラスターを 6分以上ビジーに 保てる と見込めるときだけ起動 残作業が6分未満と見込んだクラス ターを停止対象にする 定期ジョブなど、少しqueue してもいいもの デフォルト Economy デフォルトが Standard なので、そのまま使わない。 少しqueueしても良いジョブなら、積極的に Economyを選ぶ 。むやみにclusterを増やさない方が圧倒的に安 いです。
  10. マルチクラスターウェアハウスの設定値 定期実行ジョブなら queue待ちは許容できる。 queueで待っている間は課金されない 。待てるジョブは待たせて、 clusterを増やさないようにする。 PARAMETER 何を制御するか 定期ジョブでの考え方 STATEMENT_QUEUED_

    TIMEOUT_IN_SECONDS queueで待てる上限 長めに取る。待っている間は課金され ない。 STATEMENT_ TIMEOUT_IN_SECONDS 実行し続けられる上限 短めに切る。暴走したクエリを課金さ れ続ける前に止める。 ※ 実際の設定値はジョブのSLAに合わせて要調整
  11. Q. スピルが発生したら、 warehouseサイズを上げなければならない? A. 必ずしもそうではない。 先ほどの通り、サイズを上げるなら 実行時間が 1/2にな らないとコストは上がる 。スピルを消しても実行時間の

    短縮がそれに満たなければ、サイズアップは損。 ローカルディスクへのスピルで済んでいて、かつ現状の コストで許容できるなら、 そのまま使い続ける選択もあ り。
  12. Adaptive warehouseは、 コスト最適 ではなく パフォーマンス最適のユースケースで使用 やっていること やっていないこと 負荷に応じてサイズ/クラスター数を自動で調整 し、クエリ を速く・安定して返す

    コストを最小化すること。自動で上振れした分、 固定 warehouseより高くなることもある ハマるユースケース例 ・BIダッシュボードやユーザーが発行するクエリなど アクセスが不 規則で予測しづらい クエリ ・SLAでレスポンス時間を安定させたい が、都度のwarehouseサ イズ変更は運用負荷が高いケース ハマらないケース例 ・バッチのように負荷パターンが一定で事前に読める ワーク ロード(固定サイズで十分) ・クエリ量・並列度が小さく スケールの恩恵が出ないワークロー ド 狙いはパフォーマンス。コスト最適化の手段としては使わない。 (自社での比較は要確認)
  13. Snowflakeにインジェストしない選択肢 (外部テーブル /Iceberg テーブル) Snowflake データ 出力 データソース → S3

    など (raw data) クエリ ← RAW External / Iceberg → STG table → MART table Native Tableに取り込まなくていい分、 COPY INTOのコストが浮く。 ← BI / 分析
  14. 外部テーブルのパフォーマンスは意外と悪くない ・Parquet / partitionなど条件が良ければ、十分使えるケースがある ・COPY INTOしてSnowflakeに取り込むコストとの比較で考える 1.83s 4.9x 2.08s 5.5x

    1.01s 3.4x 0.38s 0.29s Native 0.42s 1.4x 外部 partition無 外部 partition有 2,000万レコードのデータで測定 Q1 全件集計 Q2 1ヶ月に絞込 全件集計は5倍遅いが、partition設計+絞込なら1.4倍まで詰まる 。COPY INTOを回収できる参照頻度が損益 分岐。低頻度参照なら外部テーブルは十分「アリ」。
  15. 外部テーブル運用イメージ 同じデータソースのテーブル群を、参照頻度でNative Table / 外部テーブルに仕分ける。 高頻度参照 → Native 約10テーブル ダッシュボードやAPIから毎日叩かれる、コア業務テーブル。

    users orders 他 5テーブル order_items payments events 低頻度参照 → 外部テーブル 約30テーブル 月次集計やアドホック分析など、参照頻度が低い履歴・ログ 系テーブル。 archived_orders api_response_cache audit_logs sensor_readings_raw legacy_customers 他 25テーブル
  16. warehouseコスト最適化データ基盤アーキテクチャ 運用状況 ワークロードをコスト重視に切り替え サイズXSでマルチクラスターを Economyに。Queue待ちを許容。 Snowflake warehouseを集約し、query_tagを運 用 → データソース

    データソースの取り込み、Snowflake のデータ更新は毎次更新 Snowflake以外にも、他部署では別 のDWHを使っている BIツールなどでビジネス指標を運用す る 毎次更新 毎次更新 ETL / ELT RAW table → 毎次更新 STG → 毎次更新 MART table 他のingest先(Data Lakeなど) table ← BI / 分析
  17. 運用パターン Viewの運用イメージ 多段Viewによるパフォーマンス劣化を避けるため、データモデリング段階でNative / Viewを仕分ける。 raw_orders table stg_order_facts table・join して作る中間テーブル

    mart_sales_summary table・さらにjoinする raw_customers table → stg_orders view・joinなし → → BI Dashboard mart_customer_orders view・単一参照のみ dim_region view・参 stg_customers view・join 照のみ なし 単純な参照だけの層はViewのまま。複数テーブルを joinして作る・激しく参照される stg_order_factsとmart_sales_summaryはNative化 し、単一参照で済む mart_customer_ordersはViewで済ませる。
  18. warehouse見直し+インジェスト見直し後のアーキテクチャ 運用状況 外部API Streamlit → → SPCS warehouse専有なし ···→ warehouseは集約し、query_tagと

    MAX_CONCURRENCY_LEVELで運用 参照 → 外部API呼び出しとStreamlitはSPCSへ 退避し、warehouseを専有しない Container Runtime RAW Native 高頻度 データソース RAWへ 書込 RAW (外部/Iceberg) STG (table) 激しく参 MART (table) join多 照 発 → 低頻度参照 warehouseは1つに集約 → STG (view) joinなし → MART (view) 単一参 BI / 分析 照 ・query_tagで用途を分ける・MAX_CONCURRENCY_LEVELでqueue許容 低頻度参照のRAWは外部テーブル /Icebergに寄せ、インジェストコストを抑 える STG/MARTはjoinの有無と参照頻度で Native / Viewを仕分ける