C データエンジニアリング — セール当日リアルタイム売上ダッシュボード BI Engine高速化 × Materialized View(capacity reservation未作成 × SELECT *で列指向キャッシュ非効率 × 事前集計マート無し × 集計粒度が細かすぎ予約容量に非乗り切り × セール時の予約サイズ固定 × パーティションプルーニング非効 × ヒット率監視なし)(MOps セール当日ダッシュボード Bad→Good)

2026-08-12 (Day 129) 水曜 C: データエンジニアリング ★★★★☆ BigQuery BI Engine / Materialized View dbt Core 1.8+ / Terraform 1.8+

概要

🧠

BI Engineは「予約」して初めて効くキャッシュ

capacity 0GBのままではBI Engineは一切機能しない。列指向のインメモリキャッシュとして予約容量を確保し、参照する列を絞ることで初めて高速化の恩恵を受けられる。

📐

ダッシュボードに必要な粒度まで事前集計する

商品×倉庫のような不要な粒度を持ったMaterialized Viewは大きくなりすぎて予約容量に乗り切らない。5分バケット×チャネルまで集計すれば桁違いに小さく保てる。

📅

イベント時のキャパシティ調整は運用として設計する

平常時の固定サイズのままセールを迎えると、キャッシュから溢れたデータへのクエリがフルスキャンに戻る。tfvars切替でレビュー可能な形にしておく。

🔔

ヒット率・使用率の監視で劣化に気づく

INFORMATION_SCHEMA.JOBS_BY_PROJECTのbi_engine_statisticsとCloud Monitoringを組み合わせ、キャッシュ効果が薄れたことをクレーム前に検知する。

問題

ECサイト MOps チームでは、セール当日に経営陣・現場責任者向けに Looker Studio で「リアルタイム売上ダッシュボード」(5分ごとに自動リフレッシュ、時間帯×購入チャネル別の売上・件数を表示)を提供している。直近のセールで、ダッシュボードの1クエリあたりのレイテンシが8〜12秒まで悪化し、かつ月間BigQueryコストも高騰した。調査すると、以下のTerraform(BI Engine予約構成)・dbtモデル(Materialized View)・Looker Studioが発行するクエリには7つの設計・コスト上の問題が潜んでいる。

問題点を全て洗い出しBigQuery BI Engine capacity reservation(列指向インメモリキャッシュ)× Materialized Viewによる事前集計 × ダッシュボードに必要な粒度への集計設計 × パーティションプルーニングを効かせるWHERE句設計 × セール時のBI Engine予約サイズの動的引き上げ × BI Engineヒット率/スロット消費の監視を活用したBad→Goodリファクタリングを行ってください。

制約・前提条件

  • BigQuery Standard SQL(GA機能のみ。BI Engine, Materialized View は共にGA機能)
  • dbt Core 1.8+(Materialized Viewは materialized='materialized_view' で定義可能)
  • Terraform 1.8+(google プロバイダー 5.x、google_bigquery_bi_reservation リソース使用可)
  • ソーステーブル: orders.order_itemsorder_id, order_date DATE, order_ts TIMESTAMP, product_id, warehouse_id, channel, qty, unit_price。partition: order_date)。セール当日は日次数千万〜億行規模に達する
  • BI Engine reservationは現在未作成(capacity 0GB)で、ダッシュボードの集計クエリは毎回フルスキャン相当のスロット処理が発生している
  • Looker Studio側のクエリは orders.order_items を直接 SELECT * で参照し、WHERE order_date の範囲指定が無い
  • BigQueryはオンデマンド課金($5/TB)。セール当日はダッシュボードの閲覧者数(同時アクセス)も平常時の10倍に増える
  • ダッシュボードで実際に必要な集計粒度は「5分バケット × 購入チャネル」の売上合計・件数のみで、商品別・倉庫別の内訳は不要
期待する回答形式: 問題点の列挙(番号付き)+ 改善後 Terraform コード(BI Engine reservation)+ 改善後 dbt モデル・schema.yml(Materialized View)+ 改善後 Looker Studio 側クエリ設計方針 + 実行例(input→output)+ 設計意図の説明

悪いコード (Before)

この構成には 7つの設計・コスト上の問題 が隠れています。見つけてみてください。
bad_dashboard_query.sql — BI Engine未予約・SELECT *・範囲指定なし
-- Looker Studioが5分ごとに発行するクエリ
-- 問題①: BI Engine reservationがcapacity 0GBで未作成
-- 問題②: SELECT *で不要列(product_id,warehouse_id,unit_price等)も読込
-- 問題③: 事前集計されたMaterialized Viewが存在せず生テーブルを直接集計
-- 問題⑥: order_dateの範囲指定が無くパーティションプルーニングが非効
SELECT *
FROM `my-project.orders.order_items`;
bad_mart_sales.sql — 粒度が細かすぎるMaterialized View
{{ config(materialized='materialized_view') }}

-- 問題④: 商品×倉庫まで持つ細かすぎる粒度
--        ダッシュボードは5分バケット×チャネルしか使わないのに
--        BI Engine予約容量(平常時10GB)に乗り切らずキャッシュミス多発
SELECT
    order_date,
    product_id,
    warehouse_id,
    channel,
    SUM(qty * unit_price) AS revenue,
    COUNT(DISTINCT order_id) AS order_count
FROM {{ source('orders', 'order_items') }}
GROUP BY order_date, product_id, warehouse_id, channel

-- 問題⑤: BI Engine予約サイズが平常時想定の固定値のまま
--        (infra/bi_engine.tf の size = 10GB 固定、セール向けの変数化なし)
-- 問題⑦: ヒット率・使用率を監視する仕組みが無い
問題点サマリー(7点)
1BI Engine reservation未作成 — capacity 0GBで一切機能しない
2SELECT *で不要列読込 — 列指向キャッシュの効率が悪化

ヒント(段階的開示)

ヒント1 — 方向性
問題は3層に分類できる。(1) キャッシュ層の不在 — BI Engineは列指向のインメモリキャッシュで、対象データが予約容量に収まっていれば集計クエリを数百ms〜数秒に高速化できるが、そもそも予約(reservation)が作られていなければ何の効果もない。(2) 集計粒度と予約サイズのミスマッチ — Materialized Viewを作っても、集計粒度が細かすぎる(商品×倉庫まで持つ)とBI Engineの予約容量に乗り切らず、キャッシュヒット率が下がる。ダッシュボードが実際に必要とする粒度(5分バケット×チャネル)まで事前に集計しておけば、はるかに小さいデータ量でBI Engineに収まる。(3) クエリ形状とスキャン範囲の設計SELECT * や範囲指定の無いWHERE句は、BI Engine・パーティションプルーニングいずれの恩恵も受けられない。加えて、セール当日はデータ量・閲覧者数が跳ね上がるため、予約サイズを固定値のまま放置すると効果が薄れる、という「イベント時に合わせて調整する運用」自体も設計に含める必要がある。
ヒント2 — アプローチ
  • 問題①: BI Engine reservationがcapacity 0GBで未作成 → google_bigquery_bi_reservation で対象ロケーションにキャパシティを確保する
  • 問題②: Looker Studioのクエリが SELECT * で不要列(product_id, warehouse_id, unit_price等)まで読み込んでいる → ダッシュボードに必要な列のみに絞る(BI Engineは列指向キャッシュなので、参照する列が少ないほど同じ予約容量でより多くの行を保持できる)
  • 問題③: 生の orders.order_items(日次数千万〜億行)を毎回直接集計しており、事前集計されたMaterialized Viewが存在しない → mart_sales_5min をMaterialized Viewとして定義し、ベーステーブルの差分のみを増分リフレッシュさせる
  • 問題④: MVの集計粒度が「注文明細×商品×倉庫」と細かすぎてBI Engine予約容量に乗り切らずキャッシュミスが多発する → ダッシュボードが実際に必要とする粒度(5分バケット×チャネル)まで事前集計し、行数を数桁小さくする
  • 問題⑤: BI Engine予約サイズが平常時のデータ量を前提にした固定値のままで、セール当日のデータ増加・閲覧者増を考慮していない → セール開催カレンダーに合わせて予約サイズを一時的に引き上げる仕組み(Terraform変数化+運用手順)を用意する
  • 問題⑥: Looker Studioのクエリに WHERE order_date の範囲指定が無く、パーティションプルーニングが効かずMV全体をスキャンしている → 「直近24時間」など明示的な範囲指定をダッシュボード側のクエリテンプレートに組み込む
  • 問題⑦: BI Engineのヒット率・スロット消費を監視する仕組みが無く、キャッシュ効果が薄れても誰も気づけない → INFORMATION_SCHEMA.JOBS_BY_PROJECT のBI Engine関連統計情報+Cloud MonitoringでBI Engineのメモリ使用率・ヒット率を可視化し、閾値を割ったらアラートする
ヒント3 — コードの骨格
-- Materialized View 集計粒度の骨格(5分バケット×チャネル)
{{ config(materialized='materialized_view') }}

SELECT
    TIMESTAMP_TRUNC(order_ts, MINUTE, 'Asia/Tokyo') AS minute_ts,
    channel,
    order_date,
    SUM(qty * unit_price) AS revenue,
    COUNT(DISTINCT order_id) AS order_count
FROM {{ source('orders', 'order_items') }}
GROUP BY 1, 2, 3
# BI Engine reservation の骨格
resource "google_bigquery_bi_reservation" "dashboard" {
  project  = var.project_id
  location = "asia-northeast1"
  size     = var.bi_engine_capacity_bytes  # セール時は変数を引き上げてapply
}

問題点分析(7点)

#問題点分類改善方法
1BI Engine reservationが未作成(capacity 0GB)キャッシュ層google_bigquery_bi_reservationで予約作成
2SELECT *で不要列まで読込キャッシュ層必要列のみに絞りキャッシュ効率最大化
3事前集計(Materialized View)が無く生テーブル直接集計コストmart_sales_5minをMV化
4MV集計粒度が商品×倉庫まで細かすぎるコスト5分バケット×チャネルまで事前集計
5BI Engine予約サイズがセール時のデータ増加を非考慮運用設計tfvars切替で一時引き上げ
6WHERE句に範囲指定が無くパーティションプルーニング非効クエリ設計直近24時間の範囲指定を必須化
7ヒット率・使用率の監視が無い監視JOBS_BY_PROJECT+Cloud Monitoringアラート

BI Engineキャッシュの仕組み — Bad vs Good の比較

Bad(変更前)— BI Engine未予約・粒度過多・監視なし google_bigquery_bi_reservation(capacity 0GB) 問題①: 予約が無くBI Engineが一切機能しない 集計クエリは毎回フルスキャン相当のスロット処理 mart_sales(商品×倉庫まで持つMV) 問題③: 生テーブル直接集計に近い粒度でMVの意味が薄い 問題④: 粒度過多でBI Engine予約容量(10GB)に乗り切らない → キャッシュミス多発 Looker Studioクエリ(SELECT * / 範囲指定なし) 問題②⑥: 不要列読込 + パーティションプルーニング非効 MV全体を毎回フルスキャン セール当日(データ10倍・閲覧者10倍) 問題⑤⑦: 予約サイズ固定・監視なしで劣化に気づけない × レイテンシ8〜12秒でダッシュボードが実用に耐えない × 同時100人の閲覧で同じ集計が並列にフルスキャンされる × 月間BigQueryコストが高騰 × キャッシュ効果が薄れても誰も気づけない Good(変更後)— 予約 × 適正粒度 × 範囲指定 × 監視 google_bigquery_bi_reservation(10GB→セール時50GB) 修正①⑤: 予約を作成しtfvars切替でセール時に引き上げ 列指向インメモリキャッシュとして機能開始 mart_sales_5min(5分バケット×チャネルのみ) 修正③④: 商品・倉庫の内訳を持たず桁違いに小さいMV 当日分でも数千〜数万行 → 予約容量に十分収まる 増分リフレッシュで最新の5分バケットまで反映 Looker Studioクエリ(必要列のみ + 直近24時間指定) 修正②⑥: キャッシュ効率最大化 + パーティションプルーニング BI Engineがヒットしレイテンシ数百ms〜1秒 セール当日(データ10倍・閲覧者10倍) 修正⑤⑦: 予約引き上げ + 使用率アラートで劣化を即検知 ✓ レイテンシが数百ms〜1秒に改善 ✓ 同時100人でもキャッシュ共有効果でコスト増を抑制 ✓ 事前集計とキャッシュヒットでスキャンコストも削減 ✓ ヒット率・使用率をクレーム前に検知できる 修正

模範解答

# infra/bi_engine.tf

variable "bi_engine_capacity_bytes" {
  description = "BI Engine予約容量(バイト単位)。平常時は10GB、セール開催時は変数を引き上げてapplyする運用"
  type        = number
  default     = 10 * 1024 * 1024 * 1024  # 10GB(平常時)
}

# 修正①: BI Engine capacity reservationを作成
resource "google_bigquery_bi_reservation" "dashboard" {
  project  = var.project_id
  location = "asia-northeast1"
  size     = var.bi_engine_capacity_bytes
}

# 修正⑤: セール開催カレンダーに合わせて容量を引き上げる運用は
#        tfvarsの切り替え(例: bi_engine_capacity_sale.tfvars で 50GB を指定)で対応。
#        Terraformコード自体は変数化しておくことで、セール前後の
#        capacity変更をコードレビュー可能な変更として履歴に残す。

# 修正⑦: BI Engineのメモリ使用率が予約容量に対して逼迫していないか監視
resource "google_monitoring_alert_policy" "bi_engine_utilization" {
  project      = var.project_id
  display_name = "BI Engine 予約容量の使用率が閾値超過"
  combiner     = "OR"
  conditions {
    display_name = "bi_engine/reservation/used_bytes が予約容量の90%を超過"
    condition_threshold {
      filter          = <<-EOT
        resource.type="bigquery_biengine_reservation"
        metric.type="bigquery.googleapis.com/biengine/reservation/used_bytes_ratio"
      EOT
      comparison      = "COMPARISON_GT"
      threshold_value = 0.9
      duration        = "300s"
    }
  }
  notification_channels = [var.oncall_notification_channel_id]
}

# 修正⑦: BI Engineでアクセラレートされなかったクエリの割合を監視
#        (INFORMATION_SCHEMA.JOBS_BY_PROJECT の bi_engine_statistics を
#         スケジュールドクエリで日次集計しモニタリングメトリクスにexport)
resource "google_bigquery_data_transfer_config" "bi_engine_hit_rate_report" {
  display_name          = "bi-engine-hit-rate-daily"
  data_source_id        = "scheduled_query"
  schedule               = "every day 07:00"
  destination_dataset_id = "monitoring"
  params = {
    query = <<-EOT
      SELECT
        DATE(creation_time) AS report_date,
        COUNTIF(bi_engine_statistics.bi_engine_mode = 'FULL') AS full_accel_count,
        COUNTIF(bi_engine_statistics.bi_engine_mode = 'DISABLED') AS disabled_count,
        COUNT(*) AS total_query_count
      FROM `region-asia-northeast1`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
      WHERE creation_time >= TIMESTAMP(CURRENT_DATE() - 1)
        AND statement_type = 'SELECT'
      GROUP BY report_date
    EOT
  }
}
Before — 商品×倉庫まで持つ細かすぎる粒度
{{ config(materialized='materialized_view') }}

SELECT
    order_date, product_id, warehouse_id, channel,
    SUM(qty * unit_price) AS revenue,
    COUNT(DISTINCT order_id) AS order_count
FROM {{ source('orders', 'order_items') }}
GROUP BY order_date, product_id, warehouse_id, channel
-- BI Engine予約容量(10GB)に乗り切らずキャッシュミス多発
After — 5分バケット×チャネルまで事前集計
-- models/marts/mart_sales_5min.sql
-- 修正③④: 生テーブルへの直接集計をやめ、ダッシュボードに
--        必要な粒度(5分バケット×チャネル)まで事前集計した
--        Materialized Viewとして定義する。商品・倉庫の内訳は
--        持たないため、同じBI Engine予約容量により多くの
--        期間のデータを収めることができる。
{{ config(
    materialized='materialized_view',
    on_configuration_change='apply',
    options={
        'enable_refresh': true,
        'refresh_interval_minutes': 5,   -- ダッシュボードのリフレッシュ間隔に合わせる
        'max_staleness': 'INTERVAL "0-0 0 0:10:0" YEAR TO SECOND',
    }
) }}

SELECT
    order_date,
    -- 5分バケットに丸める(ダッシュボードの表示粒度そのもの)
    TIMESTAMP_TRUNC(order_ts, MINUTE, 'Asia/Tokyo')
        AS minute_ts,
    DIV(EXTRACT(MINUTE FROM order_ts), 5) * 5
        AS bucket_offset_minutes,  -- 5分単位のオフセット
    channel,
    SUM(qty * unit_price) AS revenue,
    COUNT(DISTINCT order_id)  AS order_count
FROM {{ source('orders', 'order_items') }}
GROUP BY order_date, minute_ts, bucket_offset_minutes, channel
models/marts/_marts.yml — schema.yml
version: 2

models:
  - name: mart_sales_5min
    description: >
      リアルタイム売上ダッシュボード専用の事前集計マート。
      5分バケット×購入チャネル単位のみを持ち、商品・倉庫の
      内訳は持たない(BI Engine予約容量に収まるサイズを維持するため)。
    columns:
      - name: order_date
        data_type: date
        constraints: [{ type: not_null }]
      - name: minute_ts
        data_type: timestamp
        constraints: [{ type: not_null }]
      - name: channel
        data_type: string
        constraints: [{ type: not_null }]
      - name: revenue
        data_type: numeric
      - name: order_count
        data_type: int64
    tests:
      - dbt_utils.unique_combination_of_columns:
          combination_of_columns: [order_date, minute_ts, channel]
Before — SELECT * / 範囲指定なし
SELECT * FROM `my-project.orders.order_items`;
After — 必要列のみ / 直近24時間に限定
-- 修正②: revenue/order_count/channel/minute_tsのみを参照し、
--        BI Engineのキャッシュ効率を最大化する
-- 修正⑥: order_dateの範囲指定でパーティションプルーニングを効かせ、
--        MV全体ではなく直近分のみをスキャン対象にする
SELECT
    minute_ts,
    channel,
    revenue,
    order_count
FROM `my-project.marts.mart_sales_5min`
WHERE order_date >= DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL 1 DAY)
ORDER BY minute_ts;
問題修正内容効果
① BI Engine未予約google_bigquery_bi_reservationで予約作成列指向インメモリキャッシュが機能開始
② SELECT *で不要列読込必要列のみに絞る同じ予約容量でより多くの行を保持
③ 事前集計マート無しmart_sales_5minをMV化生テーブル直接集計を回避しコスト削減
④ 粒度が細かすぎる5分バケット×チャネルまで集計MVサイズが桁違いに小さくなり予約容量に収まる
⑤ 予約サイズ固定tfvars切替で一時引き上げセール時のデータ急増にも対応
⑥ 範囲指定なし直近24時間の範囲指定を必須化パーティションプルーニングでスキャン量削減
⑦ 監視なしJOBS_BY_PROJECT+Cloud Monitoringアラートキャッシュ劣化をクレーム前に検知

実行例(input → output)

input(改善前・生テーブル直接集計、セール当日のデータ量):

orders.order_items は当日だけで8,000万行。Looker Studioは SELECT * を5分ごとに実行し、BI Engine reservationも存在しない。

output(Before・問題のある実装):

毎回8,000万行に対して集計クエリのフルスキャンが走り、レイテンシ8〜12秒・1クエリあたり数百MB〜数GBのスキャン課金が発生する。閲覧者が10倍(同時100人)に増えると、同じ集計が並列に100回実行され、コストとスロット消費がほぼ線形に増加する。

output(After・改善後):

mart_sales_5min は5分バケット×チャネル単位まで事前集計されているため、当日分でも数千〜数万行程度に収まる。10GB(平常時)〜50GB(セール時)のBI Engine予約容量に十分収まり、WHERE order_date >= ... の範囲指定と合わせてBI Engineの列指向インメモリキャッシュがヒットし、レイテンシは数百ms〜1秒程度まで改善する。同時閲覧100人がほぼ同一のクエリ(同じ集計・同じ範囲)を投げるため、BI Engineのキャッシュ共有効果によりスキャンコストの増加も抑えられる。

ポイント解説

1BI Engineは「予約してはじめて効果が出る」インメモリキャッシュである — capacity 0GBのままではBI Engineは一切機能しない。列指向でデータをメモリに保持する仕組みのため、対象データが予約容量に収まっているかどうかがヒット率を決定づける。
2ダッシュボードに必要な粒度まで事前集計することがBI Engine活用の前提 — Materialized Viewを作るだけでは不十分で、「実際に画面が必要としている粒度」まで集計しておくことで、同じ予約容量により多くの期間・データを収められる。過剰な粒度(商品別・倉庫別など)を持たせると、その分だけキャッシュに乗る余地が減る。
3列指向キャッシュではSELECT *が最も相性が悪い — 参照する列を絞るほど、同じ予約容量でより多くの行数を保持できる。ダッシュボードのクエリテンプレートは「本当に表示に使う列だけ」を選択するよう設計する。
4パーティションプルーニングとBI Engineは別レイヤーで効く独立した最適化 — WHERE句で範囲を絞ることは、BI Engineの有無に関わらずスキャン量を減らす基本動作であり、両者を組み合わせて初めて最大限のコスト削減・高速化が得られる。
5イベント時のキャパシティ調整は「運用」として設計に組み込む — 平常時のデータ量を前提にした固定サイズの予約は、セールのようなスパイクに弱い。Terraformで変数化し、セール開催カレンダーに合わせてレビュー可能な変更として容量を引き上げる運用まで含めて設計する。
6監視が無ければ「効いているつもり」のキャッシュに気づかず劣化し続ける — BI Engineのメモリ使用率・アクセラレート率(INFORMATION_SCHEMA.JOBS_BY_PROJECTbi_engine_statistics)を可視化し、閾値割れをアラートすることで、キャッシュ効果の劣化をユーザーからのクレーム前に検知できる。
7「速くする」と「安くする」は同じ設計変更で同時に達成できることが多い — 事前集計による行数削減は、レイテンシ短縮とスキャンコスト削減の両方に効く。BI Engineやパーティションプルーニングも同様に、キャッシュヒットしたクエリはスロット消費・課金対象スキャン量の両方を減らす。

実務への応用

MOpsチームが扱うダッシュボードの多くは「同じ集計クエリを、多数の閲覧者が短い間隔で繰り返し実行する」という特性を持つ。このパターンでは、個々のクエリを個別最適化するより、「事前集計した小さなマート × BI Engineのようなキャッシュ層」を用意し、集計クエリそのものを軽量化する設計の方が費用対効果が高い。特にセール・キャンペーン当日のようにアクセスが急増するタイミングでは、平常時の設計のまま迎えるとレイテンシ悪化とコスト急増が同時に起きやすいため、「イベント時にキャパシティを一時的に引き上げる」運用まで事前に仕組み化しておくことが実務上重要になる。

BIツール選定にも関わる観点: BI Engineは Looker Studio だけでなく、Looker(旧LookML)やその他のBIツールからの標準SQLクエリにも適用される。ダッシュボード基盤を新規に選定する際は、BIツール側のキャッシュ機構だけでなく、BigQuery側のBI Engineをどう併用するかもセットで設計すると良い。

今日のまとめ

BI Engine × Materialized Viewによるダッシュボード高速化の7点チェックリスト: ① capacity reservationを作成しBI Engineを機能させる ② SELECT *をやめ必要列のみに絞りキャッシュ効率を最大化 ③ 生テーブル直接集計をやめ事前集計マートを用意 ④ ダッシュボードに必要な粒度まで集計しMVサイズを予約容量に収める ⑤ セール等のイベント時は予約サイズを一時的に引き上げる運用を組み込む ⑥ WHERE句の範囲指定でパーティションプルーニングを効かせる ⑦ ヒット率・使用率を監視しキャッシュ効果の劣化を検知する。 ダッシュボード高速化の本質は「同じクエリが繰り返し実行される」という特性を活かし、事前集計とキャッシュ層を組み合わせて集計コストそのものを引き下げることにあり、レイテンシ改善とコスト削減は多くの場合、同じ設計変更で同時に達成できる。

次のステップ

  • 発展問題: 現在の設計は「5分ごとにLooker StudioがBigQueryへ直接クエリを投げる」ポーリング型だが、真にリアルタイム(秒単位)な更新が必要な場合、orders.order_items へのINSERTをトリガーにPub/Sub経由でダッシュボード側にプッシュ通知する設計に変えるとどうなるか、BI Engine/Materialized Viewとの役割分担も含めて整理せよ。また、Materialized Viewの max_staleness を極端に短く(例: 30秒)設定した場合、ベーステーブルの増分リフレッシュ頻度とコストにどう影響するかを試算せよ。
  • 参考: BigQuery BI Engine(capacity reservation) / BigQuery Materialized View(max_staleness, 自動リフレッシュ) / INFORMATION_SCHEMA.JOBS_BY_PROJECTbi_engine_statistics / パーティション分割テーブルとプルーニング / Looker Studio のBigQueryコネクタ

自己評価(あとで記入)