公式ドキュメントに記載のある「BigQuery best practices」をまとめてみるシリーズ。
今回はパフォーマンスのプラクティスをまとめます。
イタリック体はドキュメントに記載のない追加コメント
ベストプラクティス
データソースに関するベストプラクティス
Control projection — Query only the columns that you need
SELECT *を避けようという話。既出のため割愛。
When querying a partitioned table, use the _PARTITIONTIME pseudo column to filter the partitions
分割テーブルは _PARTITIONTIME 列でフィルタをする。
BigQuery performs best when your data is denormalized
スキーマの非正規化を行う。
- 正規化によるストレージ容量の節約効果は薄い
- 正規化してJOINする場合、通信等のオーバーヘッドがあるが、非正規化する場合は個別のスロットで並列化されるためパフォーマンスが向上する。
- 非正規化した上でリレーションを保つには、nested field(REPEATEDやSTRUCT)を利用する。
- ただし、以下のような場合は非正規化を避ける
- スタースキーマにおいてディメンジョンの変更頻度が高い
- OLTPとしての利用(そもそもBigQuery自体が適していないと思うが)
If query performance is a top priority, do not use an external data source
パフォーマンスが大事なら、外部データソースは利用しない。
- Cloud StorageやGoogle Driveをデータソースとして利用できるが、BigQueryにデータを格納するよりもパフォーマンスは悪くなる
- 外部データソースは以下のケースで利用する
- ETL
- 頻繁に変更されるデータ
- 定期的なデータ取り込み
When querying wildcard tables, use the most granular prefix possible
複数テーブルに対してワイルドカードを用いたクエリをする場合は、できる限り絞り込んだ表現を利用する。
- 例えばdata_2010のような末尾が年度になっているテーブルがあるとして、2010年台のデータのみが欲しいのであれば、FROM data_201*は、FROM data_*よりも対象テーブルが少ないため好ましい。
スロット間のデータ移動(shuffle)に関するベストプラクティス
原文
中身は少しタイトルとあっていないかも。JOINとシャーディングの話が中心
Reduce the amount of data that is processed before a JOIN clause
JOINの前に、データ量を削減する
- JOINはshuffle(データの移動とマージ)が行われるため、shuffleが実行される以前にデータ量をwhere区などで削減することでパフォーマンス改善につながります。
Use WITH clauses primarily for readability
With句はリーダビリティのためだけに利用する。マテリアライズされるわけではないので、参照するたびにクエリが実行されます。
Do not use tables sharded by date (also called date-named tables) in place of time-partitioned tables
日付ごとにテーブルを作るのではなく、パーティション分割テーブルを利用する。
- 日付ごとにテーブルを作るアプローチは、以下のオーバーヘッドがある。
- 個別のテーブルごとにメタデータを保持する
- クエリ実行時に個別のテーブルごとに権限を確認する必要がある
- _ちなみに、日付分割されたテーブルで、読み込むテーブルを緻密に絞るには
_TABLE_SUFFIX
擬似列を利用する。
Avoid creating too many table shards. If you are sharding tables by date, use time-partitioned tables instead.
1個上で紹介したものと同じ。)
Top comments (0)