---
title: "BigQueryでお金を溶かさないコツ | grasys blog"
url: "https://blog.grasys.io/post/higuchi/bigquery-partition/"
description: "BigQueryは従量課金なので、下手なクエリを打って無駄にお金を溶かしたくはないものです。 操作ミスで高いクエリを実行してしまう大きな理由として、パーティション指定のし忘れがあると思います。 パーティション指定をし忘れを防ぐ為に、トラウマになるぐらいのパーティションを指定する反復練習をするのも一つの手ですが、パーテ…"
---

# BigQueryでお金を溶かさないコツ

-   ![](/_astro/noicon.CTHOhNiB_1HMs6A.webp)[higuchi](/authors/higuchi/)
-   公開日：2018年10月20日
-   カテゴリー：[Tech](/categories/tech/)
-   タグ：[#BigQuery](/tags/bigquery/)

![BigQueryでお金を溶かさないコツ](/_astro/og-image.DDSiu2Ny_XHpDd.webp)

BigQueryは従量課金なので、下手なクエリを打って無駄にお金を溶かしたくはないものです。

操作ミスで高いクエリを実行してしまう大きな理由として、パーティション指定のし忘れがあると思います。

パーティション指定をし忘れを防ぐ為に、トラウマになるぐらいのパーティションを指定する反復練習をするのも一つの手ですが、パーティションを指定しないとクエリが実行されない設定をするという手もあります。

下記のように「–require\_partition\_filter」を指定してテーブルを作成した上で、

Plain textcontent\_copy

```
bq mk --require_partition_filter --time_partitioning_type DAY {DATASET}.{TABLE} {SCHEMA}.json
```

クエリを実行すると、

Plain textcontent\_copy

```
bq query --nouse_legacy_sql "SELECT * FROM \`{DATASET}.{TABLE}\`
```

このように怒られます。

Plain textcontent\_copy

```
Cannot query over table '{DATASET}.{TABLE}' without a filter over column(s) '_PARTITION_LOAD_TIME',
'_PARTITIONDATE', '_PARTITIONTIME' that can be used for partition elimination
```

これで安心してクエリが叩けますね。

にしても、パーティション指定って面倒臭いですよね。

パーティション指定をした上で、WHERE句に時系列のカラムを指定するとか、パーティションを指定してバルクインサートするとか。

そんな方には「–time\_partitioning\_field {カラム名}」を指定してテーブルを作成するのがオススメです。

Plain textcontent\_copy

```
bq mk --require_partition_filter --time_partitioning_type DAY --time_partitioning_field timestamp {DATASET}.${TABLE} {SCHEMA}.json
```

仮に指定したカラムを下記のテーブルのtimestampにしたとしましょう。

Plain textcontent\_copy

```
[
  { "name" : "timestamp", "type" : "TIMESTAMP", "mode" : "NULLABLE" },
  { "name" : "user_id", "type" : "INT64", "mode" : "NULLABLE" }
]
```

まず作成したテーブルに下記のCSVをバルクインサートしてみます。

Plain textcontent\_copy

```
2018-10-20 12:00:00, 123
2018-10-21 12:00:00, 456
2018-10-22 12:00:00, 789
```

Plain textcontent\_copy

```
bq load {DATASET}.${TABLE} xxx.csv
```

すると、timestampを軸にパーティショニングがされて、 下記のようにloadされます。

{DATASET}.${TABLE}$20181020 に 「2018-10-20 12:00:00, 123」 {DATASET}.${TABLE}$20181021 に 「2018-10-21 12:00:00, 456」 {DATASET}.${TABLE}$20181022 に 「2018-10-22 12:00:00, 789」

さらにそのデータに対して下記のようにクエリを実行すると、

Plain textcontent\_copy

```
bq query --nouse_legacy_sql "SELECT * FROM \`{DATASET}.{TABLE}\` WHERE timestamp >= TIMESTAMP('2018-10-20') AND timestamp < TIMESTAMP('2018-10-21')
```

パーティション指定が不要で、しかもパーティションの20181020のみを参照してくれます。

テーブル作成の指定により、実装の工数やクエリの文字数など削減できると思うので、 考慮して指定してみるといいと思います。

## この記事を書いた人

[![](/_astro/noicon.CTHOhNiB_Z24aAgM.webp)](/authors/higuchi/)

### [higuchi](/authors/higuchi/)

higuchiのプロフィールと執筆記事をご覧いただけます。

[プロフィールと記事一覧](/authors/higuchi/)
