BigQueryのテーブルを作成する際に最初に検討すること

はじめに

BigQueryとはいえデータ量が多いと時間はかかるので、速度がある程度求められるものに関してはパフォーマンスチューニングの検討をした方が良さそう

BigQuery を最大限に活用するための重要なベスト プラクティスの 1 つが、テーブルのパーティショニングとクラスタリングです 公式ブログから引用:https://cloud.google.com/blog/ja/products/data-analytics/skip-the-maintenance-speed-up-queries-with-bigquerys-clustering

パーティショニング

公式ブログから引用

作成手順

bq mk --table \
--schema SCHEMA \
--time_partitioning_field COLUMN \
--time_partitioning_type UNIT_TIME \
--time_partitioning_expiration EXPIRATION_TIME \
--require_partition_filter=BOOLEAN \
--project_id PROJECT_ID \
DATASET.TABLE

公式から引用

分割テーブルの注意点

クラスタリング

複数カラムの指定

いわゆるインデックスのようなものなので、複数カラムで作成する場合にはMySQLの複合インデックスをイメージするとわかりやすい。同様に順序が重要で右の順序(age, last_name, first_name)で作成する場合は以下の図のようになる。

【図解】B-treeを理解し、複合インデックスの順番を正しく作るから引用

順序に関してはWHEREの頻度が高い順からインデックスをつけると良い。上記の例では、年齢から何かを調査することが多いテーブルだろう。逆にlast_nameがインデックスの先頭に来ていたら、連絡先のような名前で検索かけることが多いテーブルということがわかる。

作成手順

bq mk \
--table \
--expiration INTEGER1 \
--schema SCHEMA \
--clustering_fields CLUSTER_COLUMNS \
--description "DESCRIPTION" \
--label KEY:VALUE,KEY:VALUE \
--project_id PROJECT_ID \
DATASET.TABLE

公式から引用

パーティショニングとクラスタリングの使い分け

パーティショニングとクラスタリングの使い分け

パーティションの利用

  • 日付/時間列があり、日付/時間でフィルタするクエリがある
  • パーティションの有効期限設定を使いたい
  • dry-run でスキャン量 (費用) 見積もりを厳密に行いたい

クラスタリングをの利用

  • 複数列に対してフィルタ/集計するクエリがある
  • カーディナリティが大きく一意の列がある
  • パーティションを使うと分割粒度が小さくなりすぎ、1テーブルあたりの上限である 4,000 パーティションを超えてしまう
  • テーブル内の大部分のパーティションが頻繁に (たとえば、数分ごとに) 変更されるミューテーション オペレーションが生成される場合、パーティションは避けてクラスタリングを利用する (上限 があるため)