BigQueryでDELETE時のスキャン量をゼロにしたい ~パーティションプルーニング~

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

BigQueryでDELETE文を実行する際のスキャン量を調査しました。

特にdataformではDELETE&INSERTでデータを更新するケースもあると思います。DELETE時の不要なスキャン量を削減できないかと、本調査を行いました。

結論

パーティションまるごとDELETEする場合は、スキャン量はかかりません。

料金  |  BigQuery: Cloud Data Warehouse  |  Google Cloud
BigQuery の料金を確認する

データセットやテーブルの削除、個々のテーブル パーティションの削除、ビューの削除、ユーザー定義関数の削除に対しては課金されません。

スキャン量がかかるケース

WHERE句の書き方によってはスキャン量が発生してしまうので注意が必要です。
例)datetimeというカラムに対してWHERE句を記載

  • スキャン量ゼロ
    DELETE `table名` WHERE datetime >= DATETIME("2019-07-07 0:00:00") AND datetime < DATETIME("2019-07-08 0:00:00")
  • スキャン量発生
    DELETE `table名`WHERE datetime BETWEEN DATETIME("2019-07-07") AND datetime("2019-07-07 23:59:59");

→”2019-07-07 23:59:59.001″等のデータが存在する可能性があり、パーティション全体をカバーしていない。BigQueryはパーティション内の各行をスキャンして条件に合致するかを調べる必要があり、スキャン量が発生してしまう。

結論:WHERE句はパーティション単位で指定する

パーティション全体をカバーするために、DATETIMEでWHERE句を記載するのではなく、パーティションの単位(下記例の場合はDATE)でWHERE句を記載するとよい。下記の記載方法であれば、スキャン量はゼロ。

DELETE `table名`  WHERE DATE(datetime) BETWEEN DATE("2019-07-07") AND DATE("2019-07-07 23:59:59");

参考:SELECTであればどちらも同じスキャン量

DELETE文の場合は、WHERE句の書き方でスキャン量が変わりましたが、SELECT文の場合は下記いずれもスキャン量は一致していました。
  • SELECT * FROM `table名` WHERE datetime >= DATETIME("2019-07-07 0:00:00") AND datetime < DATETIME("2019-07-08 0:00:00")
  • SELECT * FROM `table名`WHERE datetime BETWEEN DATETIME("2019-07-07") AND datetime("2019-07-07 23:59:59");

まとめ

いかがだったでしょうか。

今回は、DELETE時の不要なスキャン量を削減するためのWHERE句の書き方をご紹介しました。

本記事が参考になれば幸いです。

タイトルとURLをコピーしました