Share
Embed
Snowflakeのコスト最適化を支えるアーキテクチャ設計
Snowflakeのコスト最適化を、設定やSQLチューニングだけでなく、アーキテクチャ設計の観点から整理します。Icebergを活用した不要なデータ取り込みの削減、要件に応じた取り込み方式の選択、データ共有によるコピーの削減、ウェアハウスの集約と分離の判断を、実践例を交えて紹介します。
Tatsuya Koreeda
September 11, 2026
Transcript
48 slides
-
自己紹介 名前 是枝 達也 / Tatsuya Koreeda 略歴 株式会社 GA
technologies, Data本部 Data Managementチーフ 肩書き・活動 ・Snowflake Data Superhero 2026 ・Snowflake UG リーダー( WEST / HCLS) 趣味 バイオインフォマティクス研究 Snowflakeで好きな機能 Snowpark Container Service -
AGENDA 1 はじめに 2 warehouseの使い方を見直す 3 インジェストを見直す 4 Icebergを効果的に使う 5
AI Ready へ近づける 6 まとめ -
コスト最適化する仮想のデータ基盤アーキテクチャ 運用状況 ワークロードはパフォーマンスよりも コスト最適に振りたい RAW/STG/MARTのwarehouseは サイズMで処理している。マルチクラ スターも使用 部署ごとにwarehouseを区切ってい る データソースの取り込み、
Snowflakeデータ更新は毎次更新 Snowflake → データソース 毎次更新 毎次更新 ETL / ELT RAW table → 毎次更新 STG → 毎次更新 table MART table 他のingest先 (Data Lakeなど) Snowflake以外にも、他部署では別 のDWHを使っている BIツールなどでビジネス指標を運用 する 今回、こちらのデータ基盤アーキテクチャをコスト最適化させていきます ← BI / 分析 -
大部分のコストは 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% -
warehouseの価値は、 マイクロパーティション最適化のクエリ処理 warehouseの最大の価値 Snowflake専用のマイクロパーティションに最適化されたコン ピュートリソース。この最適化を最大限活かせるかが、使いこなし の鍵。 裏を返すと クエリ処理以外の汎用的な処理は、warehouseではなく汎用的 なコンピュートリソースに寄せるべき。 出典:Snowflake
Documentation「テーブルの構造:マイクロパーティションとデータクラスタリング」 https://docs.snowflake.com/ja/user-guide/tables-clustering-micropartitions -
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レスポンス待ち(課金される) -
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に切り離せる -
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中心の処理は、最初からこちら側に置く。 -
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 -
AUTO_SUSPENDの設定値 ワークロード 結論 A|1分以上のクエリ 短い値が有利 。実行時間が60秒を超えるので、待機ぶんがそのま ま無駄になる。 B|数秒のクエリが数秒間隔 長めの値が有利 。短くすると起動が分かれ、最低60秒課金を何度
も踏む。 C|実行時間・間隔が様々 勘では決まらない 。設定値で起動回数が変わるので、クエリ履歴か らシミュレーションして決める。 出典:井上樹「このSnowflakeウェアハウスの自動停止時間は何秒が最適なのか?クエリ履歴から算出するコスト最小化検証実験(超節約生活実験)」NTT DATA TECH (Zenn), 2025年12月1日 https://zenn.dev/nttdata_tech/articles/9df82505179e8a(著者の方に掲載許諾を取得済み) -
マルチクラスターウェアハウスのコストは 「サイズ × クエリ処理時間 × クラス ター数」の体積で表せる x軸:クエリ処理時間 warehouseがクエリを処理 している時間。
クラスターが増えるごとに、料金は 倍々になっていく。 -
マルチクラスターウェアハウスの scaling policy SCALING_POLICY クラスターを起動する条件 シャットダウンする条件 向いているワークロード Standard クエリがqueueした /
現在のクラス ターでは捌けないと判断した時点で すぐ起動 負荷の低い状態が続いたら、最も空 いているクラスターから停止 待たせたくないクエリ 追加クラスターを 6分以上ビジーに 保てる と見込めるときだけ起動 残作業が6分未満と見込んだクラス ターを停止対象にする 定期ジョブなど、少しqueue してもいいもの デフォルト Economy デフォルトが Standard なので、そのまま使わない。 少しqueueしても良いジョブなら、積極的に Economyを選ぶ 。むやみにclusterを増やさない方が圧倒的に安 いです。 -
マルチクラスターウェアハウスの設定値 定期実行ジョブなら queue待ちは許容できる。 queueで待っている間は課金されない 。待てるジョブは待たせて、 clusterを増やさないようにする。 PARAMETER 何を制御するか 定期ジョブでの考え方 STATEMENT_QUEUED_
TIMEOUT_IN_SECONDS queueで待てる上限 長めに取る。待っている間は課金され ない。 STATEMENT_ TIMEOUT_IN_SECONDS 実行し続けられる上限 短めに切る。暴走したクエリを課金さ れ続ける前に止める。 ※ 実際の設定値はジョブのSLAに合わせて要調整 -
Q. スピルが発生したら、 warehouseサイズを上げなければならない? A. 必ずしもそうではない。 先ほどの通り、サイズを上げるなら 実行時間が 1/2にな らないとコストは上がる 。スピルを消しても実行時間の
短縮がそれに満たなければ、サイズアップは損。 ローカルディスクへのスピルで済んでいて、かつ現状の コストで許容できるなら、 そのまま使い続ける選択もあ り。 -
Adaptive warehouseは、 コスト最適 ではなく パフォーマンス最適のユースケースで使用 やっていること やっていないこと 負荷に応じてサイズ/クラスター数を自動で調整 し、クエリ を速く・安定して返す
コストを最小化すること。自動で上振れした分、 固定 warehouseより高くなることもある ハマるユースケース例 ・BIダッシュボードやユーザーが発行するクエリなど アクセスが不 規則で予測しづらい クエリ ・SLAでレスポンス時間を安定させたい が、都度のwarehouseサ イズ変更は運用負荷が高いケース ハマらないケース例 ・バッチのように負荷パターンが一定で事前に読める ワーク ロード(固定サイズで十分) ・クエリ量・並列度が小さく スケールの恩恵が出ないワークロー ド 狙いはパフォーマンス。コスト最適化の手段としては使わない。 (自社での比較は要確認) -
Snowflakeにインジェストしない選択肢 (外部テーブル /Iceberg テーブル) Snowflake データ 出力 データソース → S3
など (raw data) クエリ ← RAW External / Iceberg → STG table → MART table Native Tableに取り込まなくていい分、 COPY INTOのコストが浮く。 ← BI / 分析 -
Native / 外部テーブルの使い分け Native Table ・何度も重い処理を回す ・よく参照され、joinされる 外部テーブル ・S3など外部ストレージに定期的にデータがロードされる ・Snowflakeに取り込むほど高頻度では
ない ・単一テーブルに対してクエリする どう使うデータなのかで決める。 (自社ワークロードでの当てはめは要確認) -
外部テーブルのパフォーマンスは意外と悪くない ・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を回収できる参照頻度が損益 分岐。低頻度参照なら外部テーブルは十分「アリ」。 -
外部テーブル運用イメージ 同じデータソースのテーブル群を、参照頻度で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テーブル -
まとめ 今日話した 3つの視点 1 warehouse 使い方を見直す warehouseのコストがsnowflakeは大半を占める。効果的な設定を行おう 2 そもそもデータインジェストするかどうか見直す クエリする=取り込む、ではない。外部のデータソースの参照をうまく利用する
3 Icebergで選択肢を増やす Icebergはどの企業でも活用用途がある。AI Readyな基盤の潮流にもなる -
warehouseコスト最適化データ基盤アーキテクチャ 運用状況 ワークロードをコスト重視に切り替え サイズXSでマルチクラスターを Economyに。Queue待ちを許容。 Snowflake warehouseを集約し、query_tagを運 用 → データソース
データソースの取り込み、Snowflake のデータ更新は毎次更新 Snowflake以外にも、他部署では別 のDWHを使っている BIツールなどでビジネス指標を運用す る 毎次更新 毎次更新 ETL / ELT RAW table → 毎次更新 STG → 毎次更新 MART table 他のingest先(Data Lakeなど) table ← BI / 分析 -
materializeする理由がなければ Viewを活用 ・中間レイヤーはViewにする。tableのbuild時間を短縮する ・※同じ重い処理を何度も実行するなら、当然Table化した方がいい Snowflake 毎次更新 データソース → S3 クエリ
← RAW 外部 table → STG view → MART view ← BI / 分析 -
運用パターン 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で済ませる。 -
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を仕分ける