0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BigQueryでCAST(STRING)がパーティション/クラスタリングのプルーニングを無効化する話

0
Posted at

はじめに

BigQueryでパーティション(日付など)とクラスタリング(特定カラム)を設定したテーブルに対してクエリを投げる際、WHERE句の書き方一つでスキャン量が桁違いに変わることがあります。

今回、テスト実施中に「WHERE句で絞り込んでいるはずなのに、なぜかフルスキャンになっている」という事象に遭遇したので、原因と対策をまとめます。

前提

対象テーブルはおおよそ以下のような設計でした。

  • パーティション:日付カラムで日次パーティション
  • クラスタリング:特定のキーカラム(例:店舗コードなど)

想定では、WHERE句で日付とキーカラムを条件指定すれば、該当するパーティション・クラスタブロックのみを読みに行き、スキャン量は小さく抑えられるはずでした。

問題現象

テスト実施中、あるクエリのスキャンバイト数を確認したところ、想定よりも大幅に大きい値になっていました。

具体的には、同じ条件で絞り込んでいるはずのクエリなのに、書き方の違いだけで以下のような差が出ていました。

  • 修正前(CASTあり):約 60GB スキャン
  • 修正後(CASTなし):約 40MB スキャン

1000倍以上の差です。金額・実行時間の両方に直結するため、看過できない問題でした。

原因

原因は、WHERE句の中でパーティション/クラスタリング対象のカラムに対して CAST(... AS STRING) のような型変換をかけていたことでした。

イメージとしては、以下のようなクエリです。

-- スキャン量が膨れ上がるパターン
SELECT *
FROM `project.dataset.table`
WHERE CAST(partition_date AS STRING) = '2026-07-01'
  AND CAST(cluster_key AS STRING) = '1234'
-- 本来意図していたパターン
SELECT *
FROM `project.dataset.table`
WHERE partition_date = DATE('2026-07-01')
  AND cluster_key = 1234

BigQueryのクエリオプティマイザは、パーティション・クラスタリングによるプルーニング(不要なブロックの読み飛ばし) を、対象カラムに対する式が「素直な比較」である場合にのみ適用できます。

対象カラムに CAST などの関数を挟んでしまうと、オプティマイザはその式の結果がどのパーティション/ブロックに対応するかを事前に判断できなくなり、プルーニングを諦めて全ブロックを読みに行く=フルスキャン という挙動になります。

これはBigQueryに限った話ではなく、パーティションプルーニングを持つ多くのDWH製品に共通する考え方ですが、実際に1000倍単位の差として体感すると、影響の大きさを実感しました。

検証方法

修正前後でクエリ実行前に確認できる「処理予定バイト数」を比較することで、CASTの有無による差分を確認できます。

  • BigQuery Console:クエリエディタでクエリを入力すると、実行前に「This query will process X bytes」という見積もりが表示される
  • bq query --dry_run でも同様にスキャン量の見積もりが取得可能

型を揃えたクエリと揃えていないクエリを両方dry runし、見積もりバイト数を比較するだけで、プルーニングが効いているかどうかの当たりがつけられます。

対策

  • WHERE句でパーティション/クラスタリング対象のカラムを条件指定する際は、カラムの型とリテラルの型を一致させる(CASTを挟まない)
  • 上流のデータ型が不統一な場合、クエリ側でCASTして帳尻を合わせるのではなく、書き込み時点で型を揃えておくことが望ましい
  • 既存のクエリ資産がある場合、パーティション/クラスタリング対象カラムに対する CAST の有無を横断的にチェックする価値がある

まとめ

パーティション・クラスタリングを設定していても、WHERE句の書き方次第でその恩恵を受けられないことがあります。特に「型が合っていないのでとりあえずCASTする」という書き方は、動作上は問題なく見えるため気づきにくい落とし穴です。

BigQueryのパフォーマンス調査をする際は、実行計画やスキャン量だけでなく、「WHERE句の対象カラムに余計な関数を挟んでいないか」も確認observation項目に加えることをお勧めします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?