BigQueryのパーティションフィルタを必須にするとどうなるのか

こんにちは。SCSKの磯野です。

BigQueryのパーティションフィルタについて、気になったことをいくつか調べてみました。

パーティションフィルタとは

パーティションフィルタを有効にすると、パーティション列を適切に指定したWHERE句が存在しないときに、エラーとすることができます。これにより、必ずパーティションが効くクエリしか実行できなくなるため、フルスキャンによる高額課金を防止することができます。

 

パーティションフィルタを有効にする方法

terraformで管理している場合、以下の一文を追加することでパーティションフィルタを有効にすることが可能です。

require_partition_filter = true

 

なお、テーブル作成後でもパーティションフィルタを有効化することは可能です。参考

パーティション分割テーブルを作成するときに、パーティション フィルタを要求するオプションを有効にしない場合でも、テーブルを更新してオプションを追加できます。

 

動作検証

検証方法

BigQueryの公開データセットを使っています。

bigquery-public-data.wikipedia.pageviews_2024を自分のプロジェクトへコピーし、パーティションフィルタの設定を変えて検証してみました。

本テーブルはサイズが大きいため、パーティションフィルタを無効にした状態での実行は自己責任でお願いいたします。

パーティションフィルタを有効にすると?

有効化前(パーティションフィルタ省略可能)

パーティションフィルタを省略可能な状態にしたままクエリを実行すると、フルスキャンが走ることが確認できました。

有効化後(パーティションフィルタ必須)

パーティションフィルタを必須にした状態でクエリを実行すると、where句がないためエラーとなることが確認できました。

WHERE句を誤って指定していても、パーティションフィルタは効く?

では、パーティションが効かないようなwhere句を指定した場合はどうなるでしょうか?

以下のようなクエリで試してみました。本クエリは、パーティション列(datehour)によるwhere句が記載されていますが、パーティショニングが効かず、フルアクセスとなってしまいます。

SELECT
*
FROM `myproject.mydateset.wikipedia_pageviews_2024` -- 公式データセットをコピーしたテーブル

WHERE
DATETIME_ADD(datehour, INTERVAL 9 HOUR) BETWEEN "2024-7-3 9:00:00" AND "2024-7-3 15:00:00";
本データ場合、datehourはTIMESTAMP型であるためDATETIME_ADDではなくTIMESTAMP_ADDを使用するのが適切です。検証のために意図的にDATETIME_ADDを使用していますが、TIMESTAMP_ADDを使用すれば、パーティショニングが効き、フルスキャンを避けることができます。

有効化前(パーティションフィルタ省略可能)

パーティショニングが効かないクエリのため、フルスキャンが走ることが確認できました。

有効化後(パーティションフィルタ必須)

パーティションフィルタが効いており、エラーとなることが確認できました。

パーティションフィルタは、where句が適切でないことを認識できています。

Jupyter Notebookからクエリを実行しても、パーティションフィルタは効く?

import pandas as pd
from google.cloud import bigquery

client = bigquery.Client(project=project_id)

# クエリを定義
query = """
SELECT
*
FROM `myproject.mydateset.wikipedia_pageviews_2024`
WHERE
DATETIME_ADD(datehour, INTERVAL 9 HOUR) BETWEEN "2024-7-3 9:00:00" AND "2024-7-3 15:00:00";
"""

# クエリを実行して結果をDataFrameに読み込む
df = client.query(query).to_dataframe()

# 結果を表示
print(df.head())

Cloud Shellエディタより試しましたが、以下のようにエラーとなり、パーティションフィルタが効いていることが確認できました。

BadRequest: 400 Cannot query over table ‘myproject.mydateset.wikipedia_pageviews_2024’ without a filter over column(s) ‘datehour’ that can be used for partition elimination; reason: invalidQuery, location: query, message: Cannot query over table ‘myproject.mydateset.wikipedia_pageviews_2024’ without a filter over column(s) ‘datehour’ that can be used for partition elimination

 

結論

パーティションフィルタは、単純に「パーティション列を使用したwhere句の有無」をチェックしているのではなく、「パーティションが効くクエリかどうか」をチェックしていることがわかりました。

パーティション列を使用したwhere句を書いていても、不適切な書き方だとパーティションが効かないことがあります。そのような場合でも、パーティションフィルタを有効にしていればエラーとなるため、意図しないフルスキャンを防止することができます。

また、コンソールだけではなくノートブックからの実行でも、パーティションフィルタは効くことがわかりました。

本記事が皆様のお役に立てれば幸いです。

著者について

データエンジニア。データ分析基盤の開発を主に担当しています。AWS・GCP学習中です!

磯野桃子をフォローする

クラウドに強いによるエンジニアブログです。

SCSKクラウドサービス(Google Cloud)は、Google Cloudの多彩なAIや各種サービスを活用したワンストップソリューションを提供します。SCSKのノウハウや体制を有効活用し、業務課題の解決に必要な全体検討と組み合わせで、最適な業務実装まで支援します。

Google Cloudデータ分析・活用基盤
シェアする
タイトルとURLをコピーしました