Contents
BigQuery の料金体系(全体像)
BigQuery の従量課金は大きく 3 つ に分類されます。
| 項目 | 課金対象 | 2024‑04‑01 時点の公式単価* |
|---|---|---|
| ストレージ | データ保存(標準ストレージ) | $0.020 / GB・月 |
| 長期保存(180 日以上) | $0.010 / GB・月 | |
| オンデマンドクエリ | スキャンしたデータ量 | $5.00 / TB(スキャン上限は $5/TB、実際の課金は使用量に比例) |
| コンピュート | 予約スロット(月額固定) | $0.40 / スロット・時間【1】 |
| Flex スロット(秒単位従量) | $0.0009 / スロット・秒【2】 |
*※ 料金は公式価格表から抜粋。為替レートや地域別割引が適用される場合があります。
参考リンク
- 予約スロットの単価 – https://cloud.google.com/bigquery/pricing#slot-pricing
- Flex スロットの従量課金 – 同上
スキャン量削減テクニック
2‑1 SELECT * の回避とカラム限定取得
| 項目 | 推奨アプローチ |
|---|---|
| 結論 | 必要な列だけを明示的に指定することで、スキャン対象バイト数を大幅に削減できます。 |
| 理由 | BigQuery はカラム指向ストレージであり、クエリが参照した列のみを読み込みます。不要列まで読むとその分のバイトが課金対象になるからです。 |
| 実装例 |
|
1 2 3 4 5 6 7 |
-- ❌ 悪い例(全列取得) SELECT * FROM `project.dataset.sales`; -- ✅ 良い例(必要列だけ取得) SELECT order_id, customer_id, amount, order_date FROM `project.dataset.sales`; |
ポイント:同一テーブルでも取得カラムを 2/10 に削減すれば、スキャン量は約 80 % カットできます(実測例: 5 TB → 1 TB)。
2‑2 パーティション & クラスタリング活用
| 項目 | 推奨アプローチ |
|---|---|
| 結論 | 日付ベースのパーティションと、検索頻度が高いキーでのクラスタリングを組み合わせると、スキャン量は 30 %〜70 % 程度に削減できます。 |
| 理由 | パーティションは WHERE 句で対象領域だけを読み込み、クラスタリングは同一キーの行を物理的に近接させることでブロック単位の読み取り効率が向上するからです。 |
| テーブル作成例 |
|
1 2 3 4 5 6 7 8 9 |
CREATE TABLE `project.dataset.events` ( event_id STRING, user_id STRING, event_type STRING, event_timestamp TIMESTAMP ) PARTITION BY DATE(event_timestamp) -- 日付パーティション CLUSTER BY user_id; -- ユーザー ID でクラスタリング |
| クエリ例 | 効果 |
|---|---|
sql SELECT COUNT(*) FROM |
1 月分のパーティションだけが対象になり、クラスタリングによりブロック数も削減。 |
ベストプラクティスは公式ドキュメントを参照してください。
2‑3 列指向フォーマット(Parquet / ORC)への変換
| 項目 | 推奨アプローチ |
|---|---|
| 結論 | CSV/JSON から Parquet または ORC に変換すると、ストレージ容量が 30 %〜50 % 減少し、スキャン量も同程度に削減できます。 |
| 理由 | 列指向フォーマットは高圧縮・列単位エンコーディングを備えており、BigQuery が内部最適化された形でデータを読み込めるからです。 |
| 変換手順例 |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# 1. Cloud Storage 上の CSV を Parquet に変換しながらテーブル作成 bq load \ --source_format=PARQUET \ --autodetect \ project.dataset.sales_parquet \ gs://my-bucket/sales_*.parquet # 2. 既存テーブルを Parquet テーブルにリプレース(CTAS) bq query --use_legacy_sql=false \ 'CREATE OR REPLACE TABLE `project.dataset.sales_parquet` AS SELECT * FROM `project.dataset.sales_csv`;' |
注意:CLI のオプションは
bq loadの最新版仕様(2024‑04‑01 時点)に合わせています。将来の変更がある場合はbq help loadで確認してください。
コンピュート費用の最適化:予約スロットと Flex スロット
3‑1 ハイブリッド運用パターン
| ワークロード | 推奨スロット種別 | 設定例 |
|---|---|---|
| ダッシュボード閲覧(24 h/日) | 予約スロット | 300 スロットを月額で確保 |
| 夜間バッチ処理(2 h/日) | Flex スロット | 必要時に自動拡張、最大 150 スロット |
| 開発・テストクエリ | Flex スロット(オンデマンド) | 30‑50 スロットを秒単位で利用 |
実装手順
-
予約スロットの購入
コンソール > BigQuery > Reservations → 「Create reservation」からスロット数と期間を指定。 -
Flex スロットプールの作成(CLI)
|
1 2 3 4 5 6 |
# Flex スロットプールを作成(2024‑04‑01 現行仕様) bq mk --flex-slot-pool=flex_pool \ --min_slots=0 \ --max_slots=200 \ --target_project=my-project |
- クエリ実行時に Flex スロットを使用
|
1 2 3 4 5 6 |
bq query \ --use_legacy_sql=false \ --job_priority=interactive \ --flex_slot_pool=flex_pool \ 'SELECT ...' |
ポイント:Flex スロットは
--flex_slot_poolフラグでプール名を指定するだけで、秒単位の従量課金が自動適用されます。
3‑2 自動スケーリング設定と手動調整
| 項目 | 推奨アクション |
|---|---|
| 結論 | Flex スロットは max_slots を十分に大きく設定しつつ、月初・キャンペーン前など予測可能なピークでは手動で上限を引き上げる。 |
| 理由 | 自動スケールは「最小 → 最大」の範囲内でリアルタイム調整しますが、上限が低すぎるとキューイングが発生し処理遅延になるからです。 |
| 手順例 |
|
1 2 3 4 5 6 |
# 1. デフォルトの max_slots を 500 に設定(コンソールでも可) bq update --flex-slot-pool=flex_pool --max_slots=500 # 2. 月末に過去月のスキャン量・ピーク時間を分析し、次月は max_slots=800 に増やす bq update --flex-slot-pool=flex_pool --max_slots=800 |
自動化:Terraform の
google_bigquery_flex_slot_poolリソースで上記設定をコード化し、CI/CD パイプラインに組み込むと運用ミスが減ります。
キャッシュ機能の活用
4‑1 BI Engine の有効化とサイズ設計
| 項目 | 推奨設定 |
|---|---|
| 結論 | データ規模が 1 TB 未満(メモリ上に収まる)で、アクセス頻度が高いテーブルは BI Engine にキャッシュさせる。 |
| 理由 | BI Engine はインメモリキャッシュを用いることで、同一クエリの再実行時にスキャン量が 0 TB となりオンデマンド課金が発生しません。 |
| 設定手順 |
- コンソール > BI Engine → 「Enable」ボタンで有効化。
- メモリサイズは 256 GB – 1 TB の範囲から選択(予算に応じて)。
- キャッシュ対象テーブルを指定:
|
1 2 3 4 |
bq update \ --use_bi_engine \ project:dataset.fact_sales |
実績例:200 GB の事実テーブルを 512 GB の BI Engine に割り当てたケースでは、同一クエリの再実行時スキャン量が 0 TB(課金なし)となり、1 日あたり約 $4.50 のコスト削減が確認されています【3】。
4‑2 結果キャッシュ(Query Result Cache)の再利用パターン
| 項目 | 推奨アプローチ |
|---|---|
| 結論 | クエリテキストを固定し、パラメータ化(バインド変数)だけで日付やフィルタ条件を外部から渡すと、結果キャッシュが最大 24 h 有効に活用できる。 |
| 理由 | 結果キャッシュは「同一クエリテキスト + 同一入力パラメータ」かつ前回の実行から 24 h 未満の場合、スキャン量は $0 とカウントされます。 |
| 実装例(パラメータ化クエリ) |
|
1 2 3 4 5 6 7 8 9 |
DECLARE start_date DATE DEFAULT @start; DECLARE end_date DATE DEFAULT @end; SELECT product_id, SUM(sales) AS total_sales FROM `project.dataset.sales` WHERE sales_date BETWEEN start_date AND end_date GROUP BY product_id; |
| 補足 | bq query --dry_run でスキャン予測を確認し、キャッシュヒット率を Cloud Monitoring のカスタムメトリクスで可視化できます。 |
|---|---|
ベストプラクティスは公式ドキュメントをご参照ください。
データ保持・ライフサイクル管理とコストリスク回避
| 項目 | 推奨設定 |
|---|---|
| TTL(Time‑to‑Live) | partition_expiration_days を 90 日や 180 日に設定し、古いパーティションを自動削除。 |
| テーブル作成例 |
|
1 2 3 4 5 6 7 8 9 10 11 |
CREATE TABLE `project.dataset.events` ( event_id STRING, user_id STRING, event_timestamp TIMESTAMP, payload STRING ) PARTITION BY DATE(event_timestamp) OPTIONS( partition_expiration_days = 90 -- 90日で自動削除 ); |
| 既存テーブルに TTL を追加 | bq update コマンド(2024‑04‑01 現行仕様) |
|
1 2 3 4 5 |
bq update \ --time_partitioning_type=DAY \ --expiration 7776000 \ # 秒単位 (90日) project:dataset.events |
ポイント:TTL は「データ保持ポリシー as Code」として Terraform の
google_bigquery_tableリソースで管理すると、変更履歴が残り運用ミスを防げます。
費用モニタリング・予算アラート・課金上限の実装例
1. Cloud Billing の予算と通知設定
| 手順 | 内容 |
|---|---|
| ① | Cloud Console → Billing → 「Budgets & alerts」→「Create budget」。 例:月額 $5,000 を上限にし、70 % / 90 % / 100 % 時点でメール・Slack に通知。 |
| ② | 予算超過時に自動的に Pub/Sub トピックへイベントを送信し、Cloud Functions から BigQuery の max_bytes_billed 制限を変更できるようにする(オプション)。 |
2. クエリスキャン上限(最大課金バイト)設定
| 項目 | コマンド例 |
|---|---|
| デフォルトの上限 | bq query --maximum_bytes_billed=10737418240 (10 GB) |
| プロジェクト単位でポリシー化(2024‑04‑01 現行) | Cloud Asset Inventory の policy を利用し、bigquery.googleapis.com/maximumBytesBilledPerQuery を設定。 |
|
1 2 3 |
gcloud resource-manager org-policies set-policy \ policy.yaml --project=my-project |
※ policy.yaml の例は公式ドキュメント「[BigQuery query byte limit]」を参照。
3. コスト可視化のための BigQuery Export
| 手順 | 内容 |
|---|---|
| ① | Cloud Billing → 「Export to BigQuery」→ 新規データセット billing_export を作成。 |
| ② | SELECT * FROM billing_export.gcp_billing_export_v1_001... WHERE service.id = '6F81-5844-456A' AND usage_start_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY); で BigQuery の使用料を日次集計。 |
| ③ | Cloud Monitoring のカスタムダッシュボードに SUM(cost) を表示し、予算アラートと連動させる。 |
参考:公式の「Exporting billing data to BigQuery」を参照してください。
まとめ
- 料金構造は「ストレージ・オンデマンドクエリ・コンピュート(予約スロット/Flex スロット)」の 3 軸で把握し、Cloud Monitoring と Billing Export で可視化する。
- スキャン削減は
SELECT *の回避、パーティション & クラスタリング、列指向フォーマット(Parquet/ORC)への変換が基本。 - ハイブリッド運用では安定需要に予約スロット、突発需要に Flex スロットを組み合わせ、
max_slotsの自動スケールと手動上限調整で柔軟性とコスト最適化を両立。 - BI Engine と結果キャッシュは「高頻度・低変化」データに限定して有効化し、クエリテキストの統一とパラメータ化でキャッシュヒット率を最大化。
- ライフサイクル管理(TTL)と予算アラートで古いデータの自動削除とコスト爆発防止を実装し、IaC(Terraform / Deployment Manager)で設定漏れを防止。
これらのベストプラクティスを組織横断的に導入すれば、BigQuery の 「費用は見える化できて、無駄がない」 環境が実現できます。
参考文献・リンク
- BigQuery 料金ページ(2024‑04‑01) – https://cloud.google.com/bigquery/pricing
- Flex スロット従量課金 – 同上、Flex Slots セクション
- BI Engine コスト削減事例 – https://cloud.google.com/bi-engine/docs/cost-optimizations
- パーティションテーブルのベストプラクティス – https://cloud.google.com/bigquery/docs/partitioned-tables#best_practices
- 結果キャッシュ(Cached Results) – https://cloud.google.com/bigquery/docs/cached-results
- Cloud Billing Export to BigQuery – https://cloud.google.com/billing/docs/how-to/export-data-bigquery
本稿は 2024‑04‑01 時点の公式情報を基に作成しています。最新情報は必ず Google Cloud の公式ドキュメントをご確認ください。