まとめ
1ヶ月分のデータのうち2時間のタイムフレームを対象とするSelectクエリのデータ処理量は適切にパーティショニングされたテーブルでは非パーティショニングテーブルに比べ1/260に削減された。
データセットによっては巨大なデータが知らないうちに処理されBigQueryコスト大幅UPの原因になるため、データのインポートやテーブル作成の際は積極的にパーティショニングを有効化していきたい。
パーティションタイプ | 処理対象データ量 | データ量(倍率) |
---|---|---|
HOUR | 148.17 KB | 1 |
DAY | 991.27 KB | 6.69 |
MONTH | 37.6 MB | 259.98 |
なし | 37.6 MB | 259.98 |
また、パーティションキーのタイムスタンプでSelect対象を絞り込んでもデータ処理量削減につながらないため同時にパーティションキーでタイムフレームを絞るように注意したい。
テストデータセット
New York Cityタクシー乗車記録を利用する。データはParquet形式で提供され、今回利用した2022年1月のデータ量は展開後におよそ343.03 MBとなった。
https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page
インポートオプション
インポート時にテーブルをパーティショニングするには --time_partitioning_fieldと --time_partitioning_typeオプションを利用する。
--time_partitioning_field
パーティションのキーを指定する。
--time_partitioning_field tpep_pickup_datetime
--time_partitioning_type
有効な値は DAY、HOUR、MONTH、または YEAR。
インポートコマンド
time_partitioning_typeごとに異なるBigQueryテーブルを作成した。
"tpep_pickup_datetime"カラムをパーティションキーとしtime_partitioning_type を"HOUR"とにする場合
bq load --source_format=PARQUET --time_partitioning_field tpep_pickup_datetime --time_partitioning_type HOUR test.yellow_tripdata_2022-01 ./yellow_tripdata_2022-01.parquet
比較用Selectクエリ
from google.cloud import bigquery
#クライアント作成
client = bigquery.Client()
#クエリ
dataset_name="test"
table_name="yellow_tripdata_2022-01"
query = """
SELECT tpep_pickup_datetime,trip_distance,fare_amount
FROM `{}.{}`
""".format(dataset_name,table_name)
#クエリ実行
query_job = client.query(query)
クエリ実行結果
--time_partitioning_type HOUR
このクエリを実行すると、148.17 KB が処理されます
--time_partitioning_type DAY
このクエリを実行すると、991.27 KB が処理されます。
--time_partitioning_type MONTH
このクエリを実行すると、37.6 MB が処理されます。
パーティショニングなし
1ヶ月分のデータをインポートしたのでtime_partitioning_type=MONTHと同じ処理対象データ量になる。
このクエリを実行すると、37.6 MB が処理されます。
パーティションキーを自動で使ってくれないパターン
2022-01-01 12:00から14:00の間にタクシーを降りた人の乗車日時、乗車距離、運賃(チップ等含まず)を取得したい場合のSQLクエリは以下のように書ける。
SELECT tpep_pickup_datetime,trip_distance,fare_amount FROM `test2.yellow_tripdata_2022-01` WHERE tpep_dropoff_datetime between "2022-01-01 12:00:00" and "2022-01-01 14:00:00"
ここで、"tpep_dropoff_datetime"カラムはパーティションキーではないことに注意する。これだとテーブル全体が処理対象とされてしまいBigQueryが読み込むデータ量が大きくなってしまう。
このクエリを実行すると、75.19 MB が処理されます。
タクシーの移動距離にもよるが乗車時間はたとえば最大6時間と仮定できるなら"tpep_pickup_datetime"カラムで乗車時間を絞るとパーティションキーが活用され処理対象データ量が1/156に減る。これで処理時間とコスト削減につながる。
SELECT tpep_pickup_datetime,trip_distance,fare_amount FROM `test2.yellow_tripdata_2022-01` WHERE tpep_dropoff_datetime between "2022-01-01 12:00:00" and "2022-01-01 14:00:00" and tpep_pickup_datetime between "2022-01-01 08:00:00" and "2022-01-01 14:00:00"
このクエリを実行すると、492.41 KB が処理されます。