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%
$160 $120 $80 $40 $0 28施設 4/7 適用 $80 $151 $18 3/3 3/13 3/23 4/1 4/9 日次コスト 施設数(28)
施設数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で全施設の全データをフルスキャン。
たとえると: 図書館でAホテルの本を1冊棚に戻すために、毎回すべての本を床に出して並べ直している状態。本が増えるほど作業量が増える。
4
dbt(集計・加工)$3.5/日
統合データをレポート用に集計・変換。コスト正常。
5
Looker Studio / スプレッドシート
レベニュー・稼働分母・売上明細・カスタマイズシートに出力。$2.7/日。
コスト内訳(改善前)
MERGE
95%
$132
dbt
$3.5
ユーザー
$2.7
コスト上位テーブル(改善前)
御客伝票
3.5億行
$36
御客情報
9,400万行
$27
御客伝票B
2億行
$20
御客GR
6,100万行
$16
御客詳細
4億行
$14
放置リスク: 施設数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 テーブル名;

-- 旧テーブルは即ロールバック用に保持(後日削除)
タイムライン
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%削減)。
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万円
カテゴリ別削減効果
D系(データ)
86%減
$126→$18
B系(バッチ集計)
87%減
$22→$2.8
M系(マスタ)
50%減
$26→$11
M系マスタは行数が少なく(数百〜数万行)、クラスタリング効果は限定的。D/B系の大量データテーブルで大きな効果。
テーブル別 Before / After(4/9実績)
39テーブル
#テーブルBefore $/日After $/日削減率
1be_D_御客伝票$36.39$5.10-86%
2be_D_御客情報$26.85$3.07-89%
3be_B_御客伝票$20.18$2.55-87%
4be_D_御客GR$15.71$1.47-91%
5be_D_御客詳細$14.00$2.81-80%
6be_D_御客GR拡張$9.22$2.18-76%
7be_D_部屋予実$8.74$2.97-66%
8re_D_御客詳細$5.75$0.84-85%
9re_D_御客集計$4.81$0.81-83%
10re_D_御客伝票$4.42$0.68-85%
11be_D_事前決済$3.46$0.91-74%
12be_M_業者$3.22$1.64-49%
13be_M_部屋タイプ$3.22$1.64-49%
14be_M_システム$2.96$1.48-50%
15be_M_自由集計$2.75$1.36-51%
16be_M_自由集計部門$2.75$1.36-51%
17be_M_大分類$1.98$1.33-33%
18be_M_集計部門$1.98$1.33-33%
19be_M_部屋番号$1.95$0.67-66%
20be_M_業者支店$1.87$0.65-65%
21be_M_カテゴリ内容$1.86$0.65-65%
22be_M_業者集計部門$1.86$0.65-65%
23re_B_御客伝票$1.61$0.14-91%
24re_D_御客情報$1.53$0.58-62%
25re_D_部屋予実$1.37$0.52-62%
26be_M_科目種別$1.36$0.99-27%
27re_D_御客GR$0.98$0.39-60%
28re_XM_予約サイトコース$0.67$0.36-46%
29re_M_システム$0.66$0.36-45%
30re_M_部屋番号$0.66$0.36-45%
31re_M_自由集計部門$0.66$0.36-45%
32re_M_自由集計$0.66$0.36-45%
33re_M_部屋タイプカテゴリ内容$0.66$0.36-45%
34re_M_部屋タイプ$0.66$0.36-45%
35re_XM_変換システム$0.66$0.35-47%
36re_XM_予約サイト$0.66$0.36-45%
37re_D_事前決済$0.64$0.24-63%
38be_M_科目$0.63$0.33-48%
39be_B_利用者集計$0.55$0.09-84%
合計$189.33$37.57-80%
D/B系(大量データ): 平均83%削減。M系マスタ(少量データ): 平均45%削減。RE系はBEより施設数が少ないため現在のコスト小だが、施設増加時もクラスタリングで自動対応。