Daily Cost (4/9)
$17.9
-87% vs Before
Annual Savings
$45.6K
年間約680万円削減
Tables Clustered
39
全テーブル完了
Batch Errors
0
4/7〜4/9 エラーなし
Before(4/1-6 平均)
$143/日
年間 $52,200(約780万円)
After(4/9 実績)
$17.9/日
年間 $6,500(約100万円)
Daily Cost + 施設数(3/3 - 4/9)
-87%
施設数28で横ばいなのにコストが$80→$151へ+89%増加。原因はデータ蓄積(行数が日々増加)でフルスキャンのコストが膨らんだため。施設が増えればさらに加速していた。
確認済み事項
Cloud Functions コード変更不要
staging + production 全39テーブル適用完了、全テーブル行数一致
__latest ビュー正常動作
4/7-4/9 バッチエラーゼロ
クラスタリングは自動維持(施設追加時に追加アクション不要)
Data Pipeline
Step 3 がボトルネックだった
1
PMS(FrontCrew)- 各ホテル
全国 28施設 のホテル管理システムから、宿泊・売上・予約などのデータを毎日CSV出力
2
Google Cloud Storage
ホテルごとの専用バケットにCSVをアップロード。コスト問題なし。
3
Cloud Functions → BigQuery MERGE $132/日 = 95%
毎晩 02:00 JST に自動実行。28施設 x 約40テーブル = 約1,150回のMERGE。
問題: テーブルにクラスタリングがないため、1施設のMERGEで全施設の全データをフルスキャン。
問題: テーブルにクラスタリングがないため、1施設のMERGEで全施設の全データをフルスキャン。
たとえると: 図書館でAホテルの本を1冊棚に戻すために、毎回すべての本を床に出して並べ直している状態。本が増えるほど作業量が増える。
4
dbt(集計・加工)$3.5/日
統合データをレポート用に集計・変換。コスト正常。
5
Looker Studio / スプレッドシート
レベニュー・稼働分母・売上明細・カスタマイズシートに出力。$2.7/日。
コスト内訳(改善前)
コスト上位テーブル(改善前)
放置リスク: 施設数28で横ばいでもデータ蓄積で月+5%増加($80→$151の実績)。施設追加が重なると加速。レポート月額(2〜3万/施設)に対してコストが利益を圧迫する水準だった。
解決策: CLUSTER BY hotel_id
CFコード変更なし
テーブルに hotel_id のクラスタリング(索引)を追加。MERGEのSQLに既に hotel_id が条件に含まれているため、BigQueryが自動でクラスタを利用してスキャン削減。stable社のCFコードは一切変更不要。
たとえると: 図書館の本にホテル名のラベルをつけて棚を分けた。Aホテルの本を戻すときは、Aホテルの棚だけ見ればいい。
実行した手順(1テーブルあたり)
-- 1. クラスタリングつきの新テーブルを作成(データ全コピー)
CREATE TABLE `...テーブル名_new`
CLUSTER BY hotel_id
AS SELECT * FROM `...テーブル名`;
-- 2. 旧テーブルをリネーム(バックアップ)
ALTER TABLE `...テーブル名` RENAME TO テーブル名_old;
-- 3. 新テーブルを正式名に
ALTER TABLE `...テーブル名_new` RENAME TO テーブル名;
-- 旧テーブルは即ロールバック用に保持(後日削除)
CREATE TABLE `...テーブル名_new`
CLUSTER BY hotel_id
AS SELECT * FROM `...テーブル名`;
-- 2. 旧テーブルをリネーム(バックアップ)
ALTER TABLE `...テーブル名` RENAME TO テーブル名_old;
-- 3. 新テーブルを正式名に
ALTER TABLE `...テーブル名_new` RENAME TO テーブル名;
-- 旧テーブルは即ロールバック用に保持(後日削除)
タイムライン
1
4/2 問題特定
BigQueryコスト$139/日の95%がMERGEのフルスキャン。クラスタリング(hotel_id)で解決可能と判断。
2
4/7 第1弾: 上位5テーブル
be_D_御客伝票 / be_D_御客情報 / be_B_御客伝票 / be_D_御客詳細 / be_D_御客GR
staging検証 → 本番適用。翌日バッチ正常。$102/日 → $8.4/日(92%削減)。
staging検証 → 本番適用。翌日バッチ正常。$102/日 → $8.4/日(92%削減)。
3
4/8 CFコード確認
Cloud Functions(processors.py)のソースを全読み。スキーマは動的取得、MERGE文はカラム名明示指定 → コード変更不要を確認。
4
4/8 第2弾 + 第3弾: 残り34テーブル
D系5テーブル + M系/B系/XM系29テーブルを一括適用。staging 34/34 + production 34/34 全成功。
5
4/9 効果確認
全39テーブル適用後初の丸1日。$17.9/日(-87%)。バッチエラーゼロ。
残タスク
_old テーブル削除: staging + production 各39個の旧テーブルが残存。数日安定稼働確認後に削除予定。ストレージコストは微小。
日別実績
| 日付 | コスト | 前日比 | 備考 |
|---|---|---|---|
| 4/5 (土) | $144.6 | - | 適用前ベースライン |
| 4/6 (日) | $142.6 | -1% | 適用前ベースライン |
| 4/7 (月) | $150.6 | +6% | 第1弾適用(DDL含む) |
| 4/8 (火) | $46.8 | -69% | 第1弾効果 + 第2,3弾適用 |
| 4/9 (水) | $17.9 | -62% | 全39テーブル適用後 |
年間コスト比較
BEFORE
$52,200/年(約780万円)
↓
AFTER
$6,500/年
約100万円
年間削減額
$45,700
約680万円
カテゴリ別削減効果
M系マスタは行数が少なく(数百〜数万行)、クラスタリング効果は限定的。D/B系の大量データテーブルで大きな効果。
テーブル別 Before / After(4/9実績)
39テーブル
| # | テーブル | Before $/日 | After $/日 | 削減率 |
|---|---|---|---|---|
| 1 | be_D_御客伝票 | $36.39 | $5.10 | -86% |
| 2 | be_D_御客情報 | $26.85 | $3.07 | -89% |
| 3 | be_B_御客伝票 | $20.18 | $2.55 | -87% |
| 4 | be_D_御客GR | $15.71 | $1.47 | -91% |
| 5 | be_D_御客詳細 | $14.00 | $2.81 | -80% |
| 6 | be_D_御客GR拡張 | $9.22 | $2.18 | -76% |
| 7 | be_D_部屋予実 | $8.74 | $2.97 | -66% |
| 8 | re_D_御客詳細 | $5.75 | $0.84 | -85% |
| 9 | re_D_御客集計 | $4.81 | $0.81 | -83% |
| 10 | re_D_御客伝票 | $4.42 | $0.68 | -85% |
| 11 | be_D_事前決済 | $3.46 | $0.91 | -74% |
| 12 | be_M_業者 | $3.22 | $1.64 | -49% |
| 13 | be_M_部屋タイプ | $3.22 | $1.64 | -49% |
| 14 | be_M_システム | $2.96 | $1.48 | -50% |
| 15 | be_M_自由集計 | $2.75 | $1.36 | -51% |
| 16 | be_M_自由集計部門 | $2.75 | $1.36 | -51% |
| 17 | be_M_大分類 | $1.98 | $1.33 | -33% |
| 18 | be_M_集計部門 | $1.98 | $1.33 | -33% |
| 19 | be_M_部屋番号 | $1.95 | $0.67 | -66% |
| 20 | be_M_業者支店 | $1.87 | $0.65 | -65% |
| 21 | be_M_カテゴリ内容 | $1.86 | $0.65 | -65% |
| 22 | be_M_業者集計部門 | $1.86 | $0.65 | -65% |
| 23 | re_B_御客伝票 | $1.61 | $0.14 | -91% |
| 24 | re_D_御客情報 | $1.53 | $0.58 | -62% |
| 25 | re_D_部屋予実 | $1.37 | $0.52 | -62% |
| 26 | be_M_科目種別 | $1.36 | $0.99 | -27% |
| 27 | re_D_御客GR | $0.98 | $0.39 | -60% |
| 28 | re_XM_予約サイトコース | $0.67 | $0.36 | -46% |
| 29 | re_M_システム | $0.66 | $0.36 | -45% |
| 30 | re_M_部屋番号 | $0.66 | $0.36 | -45% |
| 31 | re_M_自由集計部門 | $0.66 | $0.36 | -45% |
| 32 | re_M_自由集計 | $0.66 | $0.36 | -45% |
| 33 | re_M_部屋タイプカテゴリ内容 | $0.66 | $0.36 | -45% |
| 34 | re_M_部屋タイプ | $0.66 | $0.36 | -45% |
| 35 | re_XM_変換システム | $0.66 | $0.35 | -47% |
| 36 | re_XM_予約サイト | $0.66 | $0.36 | -45% |
| 37 | re_D_事前決済 | $0.64 | $0.24 | -63% |
| 38 | be_M_科目 | $0.63 | $0.33 | -48% |
| 39 | be_B_利用者集計 | $0.55 | $0.09 | -84% |
| 合計 | $189.33 | $37.57 | -80% |
D/B系(大量データ): 平均83%削減。M系マスタ(少量データ): 平均45%削減。RE系はBEより施設数が少ないため現在のコスト小だが、施設増加時もクラスタリングで自動対応。