オンラインサービスを利用する際に気になる点の一つがコストだと思います。BiguQueryでもたまに「xx万円溶かした」的な話を聞き、BigQuery怖いと思っている方もいるかもしれません。私なりに考えていることをまとめてみました。
BigQueryのQueryのコスト構造
BigQueryのコスト構造は非常にFairで、データ量と計算量に関係しています。すなわちコストを下げるに読む必要のないデータを小さくしたり、無駄な計算を少なくすればよいのです。さらにこれはそのままパフォーマンスにも直結します。安いQueryは早いのです。逆にBigQueryのパフォーマンスを向上させるにはこれ以外ありませんし、逆説的にはこれ以上考える必要もありません。
Queryするデータの減らすためのテーブル設計
必要なデータ「だけ」にアクセスするようにします。データの選択方法にはカラム方向(列)とロー方向(行)があります。
カラム方向
SELECT * FROM table
とせずに、
SELECT column FROM table
と必要なカラム名を明示するようにします。
ロー方向
データが増えていくのは避けられませんが、トレードオフにしない方法があります。アクセスする行を減らす方法はいくつかあります。
BigQueryが提供している方法としては、
がありますが、さらに
- サンプリングしたテーブル
も選択肢に入ります。サンプリングテーブルは集計ロジックも入れれば、
- 中間テーブル(データマート)
ということもできます。
つまり、基本的にはQueryに必要のデータの凝集性を活用して、テーブルを設計(テーブルを分割、パーティショニング等)し、アクセス時にその部分だけにアクセスすることでコストを最適化しましょう。また、Queryの設計時=トライアンドエラーの際にはサンプリングテーブル等を活用すればアクセスするデータの量は減り、コストも下がり、トライアンドエラーのパフォーマンスも上がります。
中間テーブルは、生データから計算結果を保持するキャッシュとして機能し、さらにアクセス権の制御や途中の計算量を削減することにも役立つなど、コスト以上の話にはなりますが、結果としてコスト削減になっているのは間違えありません。
必要なコストを把握する
前述したようにBigQueryのQueryコスト構造は比較的単純なため(今後BigQueryML等で複雑になりつつありますが)、把握も可能です。Queryを書けばアクセスするデータ量がわかるので、 BigQuery Mate などで簡単にQueryごとのコストを事前に予測することは可能ですし、注意して使うべきです。
実際に使ったコストは、auditlogをstackdriverからbigqueryにload(sink)し、処理したByte数等を確認することで、概算することも可能です。
Queryの読み込みサイズにリミットをかける
Maximum Bytes Billed
オプションで 一つのQueryが読み込むサイズに制限をかけることができます。しかし、残念ながらこの方法だけでは、プログラム等で何度もQueryを繰り返すようなケースでは制限できません。プログラムに問題があって必要以上にQueryを繰り返してしまうような場合は、あとで気づくしかありません。(幸い、BigQueryとしてプロジェクト単位の制限はあります)
Googleさんにお願いしたいとすると
Queryごとの Maxium Byteに加えて、Query単位に加えて、月間単位で、 Budget Bytes を設定するようなことができたらありがたいかもしれません。それをアカウント単位(ユーザーアカウント、サービスアカウント)、プロジェクト単位といった粒度で簡単に設定、Budget消化状況を確認、などできると嬉しいです。また、Budgetを超えたQueryも簡単に承認して動かすなどできるととても安心できます。
とはいえ、そんなことをするより、 flat rate 契約(使い放題, 3-400万円/月という噂)してくれ、ってお話だとは思いますが、、ぜひfeedbackさせてください。
最後に
項目から公式ページにリンクを貼ろうと思って検索していたら、すでにGoogleさんがBestPracticeをまとめてくれていました。まずはここをご確認ください!!
まずは公式ドキュメントを読んでもらうのが一番でしたね。とはいえ、一番言いたかったことは、
コストも、設計して使いこなしましょう
ということでした。
終わり