Contents
1. BigQuery の料金体系と公式価格
BigQuery は大きく オンデマンド課金、固定スロット課金、ストレージ課金 の 3 種類に分かれます。各課金モデルの基本単価と適用シーンを把握することが、コスト最適化の出発点となります。
1‑1. オンデマンド課金(従量課金)
オンデマンドはクエリ実行時にスキャンしたデータ量(TB 単位)で課金されます。公式価格は以下のとおりです(米国リージョン)。
| 項目 | 料金 |
|---|---|
| データ スキャン(オンデマンド) | $5.00 / TB【1】 |
| フラットレート(割引対象外) | - |
ポイント:スキャン量が直接コストに比例するため、クエリの設計次第で大幅な削減が可能です。
1‑2. 固定スロット課金(予約スロット)
固定スロットは月額料金で一定数の処理能力(スロット)を確保します。現在の価格は $2,000 / スロット / 月(米国リージョン)です【2】。
| 項目 | 料金 |
|---|---|
| 1 スロットあたり月額 | $2,000 |
| フレックススロット(短期利用) | $2,000 / スロット / 月(最低 1 日単位で予約)【3】 |
ポイント:大量かつ継続的なクエリが見込める場合はオンデマンドよりも固定スロットの方がコスト効率が高くなることが多いです。
1‑3. ストレージ課金
保存データ量に応じた従量課金です。公式価格は次のとおりです【4】。
| タイプ | 料金 |
|---|---|
| アクティブストレージ(標準) | $0.020 / GB‑month |
| コールドストレージ(長期保存) | $0.010 / GB‑month |
ポイント:データのアクセス頻度に応じてストレージクラスを切り替えると、年間コストが 10 %〜30 % 程度削減できます。
2. コスト診断の基本フロー
実際に自社環境でどこがボトルネックかを把握するには、①使用量の可視化 → ②価格とのマッピング → ③改善余地の特定 の手順が有効です。
2‑1. 使用量データ取得
BigQuery の 監査ログ と Billing Export(BigQuery テーブル)を組み合わせると、ジョブ単位で以下情報が取得できます。
|
1 2 3 4 5 6 7 8 9 10 |
SELECT job_id, creation_time, total_bytes_processed / (1024*1024*1024) AS scanned_gb, total_slot_ms / 1000.0 AS slot_seconds, query FROM `my-project.billing_export.gcp_billing_usage` WHERE service_description = 'BigQuery' AND usage_start_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY); |
2‑2. コストマッピング例(2024 年公式価格)
| 項目 | スキャン量 (TB) | オンデマンド料金 | 想定スロット数* |
|---|---|---|---|
| 月間合計スキャン | 120 | $600 | 30 |
| ピーク時(1 時間) | 8 | $40 | 5 |
* スロット換算は $2,000 / スロット を基に概算。実際の必要スロット数はジョブのスループット要件で決定します。
2‑3. 改善余地の優先順位
| 優先度 | 改善策 | 推定削減率 |
|---|---|---|
| 高 | パーティション・クラスタリング導入 | 20 %〜30 % |
| 中 | SELECT * → 必要列限定 | 5 %〜15 % |
| 低 | フラットレート割引(長期予約) | 10 %〜25 % |
3. スキャン量削減テクニック
スキャン量はコストに直結します。以下の 3 手法は 導入ハードルが低く、即効果を実感しやすい とされています。
3‑1. パーティションとクラスタリングでデータ範囲を絞る
概要:テーブルを日付パーティション化し、頻繁にフィルタリングされるキーでクラスタリングすることで、不要領域の読み取りを防ぎます。
実装例(正しい構文)
|
1 2 3 4 5 6 |
CREATE TABLE `my_project.analytics.sales` PARTITION BY DATE(order_timestamp) -- 日付パーティション CLUSTER BY customer_id, product_category AS SELECT * FROM `my_project.raw.source_sales`; |
- 効果測定:
WHERE order_date BETWEEN '2024-01-01' AND '2024-01-31'のクエリは、対象月のパーティションだけをスキャンし、クラスタリングにより約 30 % の追加削減が期待できます【5】。
3‑2. 必要列のみを指定し、SELECT * を回避する
概要:BigQuery は列単位でデータを読み取ります。不要な列までスキャンすると無駄な I/O が発生します。
実装例
|
1 2 3 4 5 |
-- 必要なカラムだけを取得 SELECT order_id, order_timestamp, total_amount FROM `my_project.analytics.sales` WHERE order_date = '2024-07-15'; |
- ヒント:
bq show --format=prettyjson my_project:analytics.salesでスキーマ情報を確認し、分析に不要な列は除外してください。
3‑3. 高選択性フィルタを先頭に置く(WHERE 句の順序最適化)
概要:BigQuery のプランナーは左側から評価しやすいため、レコード数が少ない条件を先に書くとパーティションプッシュダウンが効きます。
実装例
|
1 2 3 4 5 6 |
SELECT * FROM `my_project.analytics.orders` WHERE status = 'CANCELLED' -- 約 2 % のレコード AND order_timestamp BETWEEN TIMESTAMP('2024-01-01') AND TIMESTAMP('2024-12-31'); |
- 効果:同一クエリでもスキャン量が約 15 % 減少するケースがあります(内部計測例は GCP ブログに掲載)【6】。
4. キャッシュ・マテリアライズドビュー活用
4‑1. マテリアライズドビューの作成と更新オプション
概要:集計結果が頻繁に参照され、基になるデータ変更頻度が低い場合は Materialized View が最適です。
正しい構文例
|
1 2 3 4 5 6 7 8 9 10 11 12 |
CREATE MATERIALIZED VIEW `my_project.analytics.daily_sales_mv` PARTITION BY DATE(order_timestamp) OPTIONS ( refresh_interval_minutes = 60 -- 1 時間ごとに自動インクリメンタル更新 ) AS SELECT DATE(order_timestamp) AS sales_date, product_category, SUM(total_amount) AS daily_total FROM `my_project.analytics.sales` GROUP BY sales_date, product_category; |
- メリット:クエリ実行時のスキャンが 0 GB(キャッシュヒット)になるため、同等集計をオンデマンドで走らせた場合と比較して最大 90 % のコスト削減が期待できます【7】。
4‑2. バッチ生成サマリテーブルの自動化
概要:日次・月次サマリを別テーブルに格納し、分析側はそれらだけを参照する設計です。
実装例(Cloud Scheduler + Cloud Functions)
|
1 2 3 4 5 6 7 8 9 |
-- 日次サマリ作成クエリ(Cloud Functions から bq コマンドで実行) INSERT INTO `my_project.analytics.sales_daily_summary` (sales_date, product_category, total_amount) SELECT DATE(order_timestamp) AS sales_date, product_category, SUM(total_amount) AS daily_total FROM `my_project.analytics.sales` WHERE order_timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY) GROUP BY sales_date, product_category; |
- 運用:このジョブを毎日 02:00 に実行すれば、分析者は数百 MB のサマリテーブルだけをスキャンし、元テーブル(TB 規模)に比べて 1/100 以下 のコストで済みます。
4‑3. クエリキャッシュと BI Engine の併用
概要:同一クエリが 24 時間以内に再実行される場合、結果キャッシュがヒットしスキャンは発生しません。BI Engine を有効化するとインメモリ最適化でキャッシュヒット率が向上します。
キャッシュヒットを狙うクエリ例
|
1 2 3 4 5 6 7 |
-- コメントは同一に保つことでテキスト一致を確保 /* daily-revenue */ SELECT product_category, SUM(total_amount) AS revenue FROM `my_project.analytics.sales` WHERE sales_date = CURRENT_DATE() - 1 GROUP BY product_category; |
- 効果:BI Engine が有効な Data Studio ダッシュボードでは、レイテンシが 0.2 秒未満 に低減し、スキャンコストは実質 $0(キャッシュヒット)になります【8】。
5. ハイブリッド課金モデルの設計指針
予約スロットとオンデマンドを組み合わせたハイブリッドモデルは、ベースライン処理は固定費で抑えつつ、ピーク時だけオンデマンドに切り替える という柔軟性が特徴です。
5‑1. 予約スロットの適正規模算出手順
概要:過去 30 日間の平均スロット使用率を基に、70 % 程度を予約スロットとして確保します。
手順
- 監査ログから月平均スロット秒数 を取得
sql
SELECT AVG(total_slot_ms) / 1000 AS avg_seconds_per_job
FROMmy_project.logging.bigquery_audit
WHERE timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY); - 1 日あたりの総スロット秒(例:24 h × 3600 s = 86,400 s)と比較し、必要スロット数 を算出
required_slots = ceil( avg_seconds_per_job / 86400 * 0.7 ) -
予約作成コマンド(Console または bq CLI)
bash
bq mk --reservation --name=my_reservation --slot_capacity=500 my-project -
期待効果:オンデマンド利用を最大 25 % 削減でき、費用の変動幅が抑えられます【9】。
5‑2. ハイブリッド課金シナリオ例
| タスク | 推奨課金モデル | 理由 |
|---|---|---|
| 日次 ETL バッチ(8 h) | 予約スロット | 長時間実行でスループットが重要 |
| 月次 KPI ダッシュボード | オンデマンド + BI Engine | 短時間・突発的アクセスに最適 |
| 緊急調査クエリ(数分) | オンデマンドのみ | コストは小さく、即時実行が必要 |
6. ストレージ最適化と新機能活用
6‑1. テーブルライフサイクル管理のインフラコード化(Terraform)
概要:テーブルごとの保持期間を自動でローテーションし、不要データの削除・コールドストレージ移行を自動化します。
Terraform 設定例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
resource "google_bigquery_table" "sales" { dataset_id = "analytics" table_id = "sales" time_partitioning { type = "DAY" expiration_ms = 2592000000 # 30 日で自動削除(ミリ秒) } lifecycle_rule { action { type = "DELETE" } condition { age = 365 # 1 年経過したパーティションを削除 } } } |
- 効果:アクティブストレージは最新 30 日分だけに限定し、古いデータは自動的にコールドへ移行または削除することで、年間 15 %〜40 % のストレージコスト削減が期待できます【10】。
6‑2. 2024 年追加の最適化機能(近似集計・JOIN 再配列・スキーマプッシュダウン)
| 機能 | 主な効果 | 使用例 |
|---|---|---|
| APPROX_COUNT_DISTINCT / APPROX_QUANTILES | 正確度を犠牲にしつつデータ量を 80 % 削減 | SELECT APPROX_COUNT_DISTINCT(user_id) FROM … |
| 自動 JOIN 再配列(2024 年リリース) | 大テーブルと小テーブルの結合順序最適化でネットワーク I/O を削減 | SELECT a.*, b.name FROM large_table a JOIN small_dim b USING (id) |
| スキーマプッシュダウン(外部テーブル) | 必要列だけを Cloud Storage から取得し、読み取りバイト数を最小化 | CREATE EXTERNAL TABLE … OPTIONS(schema_fields=[…]) |
- 実装ポイント:これらの機能は デフォルトで有効 なものが多く、特別なフラグ設定は不要です。クエリに組み込むだけで効果が得られます。
7. コストモニタリングとアラート設定
7‑1. 監査ログからスキャン量を抽出しダッシュボード化
概要:Cloud Logging の BigQuery 監査ログを定期的に集計し、プロジェクト・ラベル別のスキャン量・コストを可視化します。
集計クエリ例
|
1 2 3 4 5 6 7 8 9 |
SELECT DATE(timestamp) AS log_date, JSON_VALUE(protopayload_auditlog.serviceData.jobCompletedEvent.statistics, "$.totalBytesProcessed") / (1024*1024*1024) AS scanned_gb, JSON_VALUE(protopayload_auditlog.serviceData.jobCompletedEvent.statistics, "$.totalSlotMs") / 1000 AS slot_seconds, labels.key AS label_key, labels.value AS label_value FROM `my-project.logging.bigquery_audit` WHERE timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY); |
- 可視化:Data Studio(Looker Studio)や Google Data Studio のテンプレートを使って、「ラベル別平均スキャン量」 や 「日次コスト推移」 をグラフ化します。
7‑2. コストアラートの設定
- Billing → Budgets & alerts で月間予算上限(例:$5,000)を設定。
- アラート閾値(50 %、75 %、100 %)に応じてメール/Slack 通知を有効化。
-
アラートトリガーと同時に Cloud Functions を呼び出し、スキャン量が急増したジョブの自動タグ付けや一時停止処理を実装可能です。
-
ベストプラクティス:予算は 部門別・プロジェクト別に分割 し、担当者が直接アラートを受取れるようにすると、迅速な対策が取りやすくなります【11】。
8. まとめ
- 料金体系の把握:オンデマンド $5/TB、固定スロット $2,000/スロット/月、ストレージは $0.020/GB‑month(アクティブ)と $0.010/GB‑month(コールド)。公式ドキュメントを常に確認【1-4】。
- 使用量の可視化:監査ログ+Billing Export でジョブ単位スキャン量・スロット秒数を取得し、費用とマッピング。
- スキャン削減テクニック:パーティション&クラスタリング、列指定、フィルタ順序最適化の3本柱で最大 30 % 削減可能。
- キャッシュ活用:Materialized View(自動インクリメンタル更新)や BI Engine で再実行コストを 90 % 以上削減。
- ハイブリッド課金設計:過去データから予約スロット比率(約 70 %)を算出し、オンデマンドと組み合わせて費用変動幅を抑制。
- ストレージ最適化:ライフサイクル管理のインフラコード化と近似集計・自動 JOIN 再配列など新機能で 20 %〜40 % 削減。
- モニタリング・アラート:BigQuery 監査ログをダッシュボード化し、予算超過時に即座に通知・自動対策を実装。
上記の手順とベストプラクティスを段階的に導入すれば、年間コストを 10 %〜30 %以上削減 できる可能性があります。まずは 「使用量可視化 → コストマッピング」 のサイクルを回し、改善ポイントを洗い出すことから始めてみましょう。
参考リンク
本稿は 2024 年 10 月時点の公式情報に基づいています。価格改定や機能追加が行われた場合は、上記リンク先で最新情報をご確認ください。