BigQueryを導入した途端に請求額が想定を超えた、という相談は後を絶ちません。オンデマンド課金のわかりやすさの裏側で、SELECT *で全カラムをスキャンし続ける無意識のコスト流出が起きているケースが大半です。本記事では、オンデマンドとスロット予約の判断基準、パーティショニング・クラスタリングなどの削減テクニック5選、そして組織全体のコストガバナンスまで、BigQueryコスト管理の全体像を解説します。月額100万円を50万円に削減した実践事例も紹介します。

BigQueryのコスト構造

BigQueryのコストは「ストレージ」と「クエリ(コンピュート)」の2軸で構成されます。多くの場合はクエリが請求の大半を占めますが、どちらに寄るかはワークロードの性質次第です。履歴データをほぼ読まずに貯めるだけの用途ならストレージ比率が上がりますし、毎日数十TBをスキャンする分析基盤ならクエリ比率が9割を超えます。

【BigQueryコスト構造】

総請求額
  |
  +--> クエリ(コンピュート)
  |       |
  |       +--> オンデマンド(スキャン量課金、約$6.25/TB)
  |       |       |
  |       |       +--> 1クエリあたりスキャンしたバイト数で課金
  |       |
  |       +--> スロット予約(定額)
  |               |
  |               +--> スロット数 x 時間で定額課金
  |
  +--> ストレージ
          |
          +--> アクティブストレージ(90日以内更新)
          +--> 長期ストレージ(90日超で自動割引)

※ クエリがほとんどの場合、コスト削減の本命

ストレージは90日間更新されないテーブルが自動的に長期ストレージ料金(半額)に切り替わるため、意識しなくても最適化が進みます。一方、クエリコストは設計次第で桁単位で変わるので、削減の本命はここです。BigQuery入門も合わせてご覧ください。

オンデマンド vs スロット予約の判断基準

BigQueryの課金モデルはオンデマンドとスロット予約(Editions)の2種類があります。どちらを選ぶかは、スキャン量の安定性と予測可能性、そしてコストの上限管理の優先度で決まります。

観点オンデマンドスロット予約(Editions)
課金スキャン量(約$6.25/TB)スロット数 x 時間(定額)
予測可能性低(使った分だけ)高(上限固定)
コスト上限ガバナンスで設定予約内容で自動的に上限
向いているワークロードボリュームが少なく変動大安定した大量ワークロード
初期の判断難易度低(すぐ使える)中(スロット数の見積もり必要)
目安(月)〜5TB/月5TB/月以上
【料金モデル判断フロー】

月次スキャン量が安定していますか?
├── No  --> オンデマンド推奨
│           (ガバナンスでクォータ必須)
└── Yes --> 月間スキャン量は?
             ├── 5TB未満  --> オンデマンド
             └── 5TB以上  --> 予測可能性が高い?
                               ├── Yes --> スロット予約(Standard/Enterprise)
                               └── No  --> オンデマンド + クォータ管理

判断に迷ったら、まずオンデマンドで3〜6ヶ月運用し、実績値からスロット予約への移行を検討するのがおすすめです。クラウドDWH比較でも、他製品との料金モデルの違いを整理しています。

コスト削減テクニック5選

実践で最も効果が大きい5つのテクニックを紹介します。第一がパーティショニング、第二がクラスタリング、第三がSELECT *の回避、第四がマテリアライズドビュー、第五がBI Engineです。それぞれ単独でも効きますが、組み合わせることで50%以上の削減が可能になります。

-- パーティション + クラスタリング テーブル作成
CREATE OR REPLACE TABLE `project.analytics.events`
PARTITION BY DATE(event_timestamp)
CLUSTER BY tenant_id, event_type
AS
SELECT *
FROM `project.raw.events_staging`
WHERE DATE(event_timestamp) >= '2024-01-01';

パーティショニングで日付フィルタの効率を上げ、クラスタリングで多用するフィルタ列のスキャン量を削減、これで多くのクエリは10分の1のコストで動くようになります。加えて、SELECT *を明示カラム指定に置き換えるだけで、さらに大幅な削減が可能です。BigQueryはカラムナ型ストレージなので、使わないカラムを指定しなければそのカラムはスキャンされません。

効果測定にはINFORMATION_SCHEMA.JOBS_BY_PROJECTビューが便利です。どのクエリがどれだけスキャンしたかを正確に追跡できます。

-- 高コストクエリの特定(過去7日間)
SELECT
  user_email,
  SUBSTR(query, 1, 80) AS query_preview,
  total_bytes_billed / POW(1024, 4) AS tib_billed,
  ROUND(total_bytes_billed / POW(1024, 4) * 6.25, 2) AS usd_estimate
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
  AND job_type = 'QUERY'
ORDER BY total_bytes_billed DESC
LIMIT 20;

マテリアライズドビューは、定型的な重い集計を事前計算してキャッシュする仕組みです。インクリメンタル更新に対応しており、ベーステーブルの変更を自動で反映します。BI Engineはダッシュボード用のインメモリ層で、よくアクセスされるデータを高速化しつつコストを下げる効果があります。BI用途の頻繁なクエリには特に効きます。dbtのインクリメンタルモデルと組み合わせる運用も有効です。

コスト監視とアラート設計

最適化と並行して、コストが突発的に跳ねないようガードレールを設計することが不可欠です。BigQueryではカスタムクォータでユーザー単位・プロジェクト単位のスキャン量上限を設定できます。

# gcloudでユーザークエリクォータを設定(1日あたり1TB制限)
gcloud alpha services quota update \
  --service=bigquery.googleapis.com \
  --consumer=projects/my-project \
  --metric=bigquery.googleapis.com/quota/query/usage \
  --unit=1/d/\{project\}/\{user\} \
  --value=1099511627776

GCPのBillingアラートも併用し、プロジェクト単位の月額予算超過を検知できるようにしておきましょう。閾値は「月予算の50%、80%、100%」の3段階で設定するのがおすすめです。

組織全体のコストガバナンス

技術的な最適化だけでなく、組織としてのコストガバナンスも重要です。プロジェクト・データセット単位で「誰が使っているか」「どの用途か」を明確にし、コスト責任の所在をはっきりさせます。

階層管理単位コスト責任者主な設計事項
組織OrganizationCIO/CTO全体予算、Billing階層
部門Folder部門長部門予算、RLSポリシー
プロジェクトProjectプロダクトオーナークォータ、請求先
データセットDatasetデータオーナーアクセス権、保持期間
テーブルTableデータスチュワードパーティショニング設計

階層ごとに責任を分担することで、最適化のモチベーションと判断権限を適切に配置できます。スケーリング戦略とも併せて設計しましょう。

実践事例――月額100万円を50万円に削減した方法

SaaS事業のAnalytics基盤で実践した削減事例です。初期状態は月額約100万円、プロジェクトが15個、daily activeユーザーが数百人規模でした。まずINFORMATION_SCHEMAでTOP20のクエリを特定したところ、上位5本で全コストの約40%を占めていました。これらのクエリは共通してSELECT *、パーティション未指定、巨大ファクトテーブルへの直接クエリという3つの問題を抱えていました。

対策として、ファクトテーブルをDATE(event_timestamp)でパーティション化、tenant_idでクラスタリング、dbtモデルを全てSELECTカラム列挙型に修正、BI用の高頻度集計はマテリアライズドビューとBI Engineに移行しました。加えて、ユーザー別にカスタムクォータを設定し、暴走クエリを防止。その結果、3ヶ月で月額請求が約50万円まで削減されました。削減幅の内訳は、パーティショニング約30%、クラスタリング約10%、SELECT*削減約8%、マテビュー/BI Engine約5%です。

まとめ

BigQueryのコスト管理は、課金モデルの適切な選択と、パーティショニング・クラスタリング・SELECT *回避の3本柱が基本戦略です。加えて、組織全体のコストガバナンスとINFORMATION_SCHEMAを使った継続的なモニタリングで、「コストは見えている状態」を保ちましょう。Snowflakeのコスト最適化と比較することで、自社の要件に合ったDWH選択もクリアになります。TCO算出の観点も併せて検討してください。

よくある質問(FAQ)

Q. BigQueryのオンデマンドとスロット予約のどちらが安いですか?

月額のスキャン量が約5TB以下ならオンデマンド、それ以上ならスロット予約が一般的にコスト効率が良くなります。ワークロードの安定性、予測可能性、コスト上限管理の優先度も判断材料になります。

Q. BigQueryで最も効果的なコスト削減方法は?

パーティショニング(日付列)とクラスタリング(頻出フィルタ列)の設定が最も即効性があります。SELECT *の回避と組み合わせると50%以上の削減も可能で、実プロジェクトでも再現性の高い成果です。

Q. BigQueryのコストを事前に見積もるには?

クエリ実行前にドライラン(–dry_run)でスキャン量を確認できます。INFORMATION_SCHEMA.JOBS_BY_PROJECTビューで過去のコスト分析も可能です。dbt経由の場合は、CI段階でdry runによる事前見積もりを組み込むのがおすすめです。