BigQueryでクエリを実行する（クエリ課金される）プロジェクトの考え方

この記事は「[Google Cloud Platform Advent Calendar 2020](https://qiita.com/advent-calendar/2020/gcp)」の8日目の記事です。

# はじめに

BigQueryを使い始めた方から、よくクエリ課金の質問を受けることがあります。
今回はクエリ課金に関する考え方を整理してみました。

BigQueryの料金（ストレージ料金、クエリ料金）の考え方は次のとおりです。

- BigQueryは、データを置いていると「格納されているデータの量」に基づいて課金されます。
- BigQueryは、クエリを実行すると「処理されたバイト数」に基づいて課金されます。

公式ドキュメントの料金のページ
https://cloud.google.com/bigquery/pricing


データを置いているプロジェクトとクエリを実行するプロジェクトが同じ、という場合は、どちらも同じプロジェクトに課金されるので分かりやすいでしょう。

それでは、あるプロジェクトに置いているデータを他部門や他社へ共有したり共有されたりして、そのデータに対してクエリを実行した場合はどうなるでしょうか。

結論としては、クエリをどのプロジェクトで実行したか、によって決まります。最初に書いたクエリ料金の説明に追記すると、次のようになります。

- BigQueryは、クエリを実行すると「処理されたバイト数」に基づいて、**クエリを実行したプロジェクトに**課金されます。

# イメージ図

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/914c9438-12a7-357f-9dd4-c00eb02e9697.png)


# クエリを実行するプロジェクトの見分け方と切り替え方

## BigQueryコンソール画面

現在のプロジェクトが、クエリを実行するプロジェクトになります。
![スクリーンショット_2020-12-04_16_05_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/04e4089d-f3ae-6b0c-f37d-05130fe383a7.png)
現在PREVIEWの新UIでも同じです。
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/5b5f80ce-3104-91f9-5892-d239997e66c1.png)


プロジェクトを切り替えるには、プロジェクトのプルダウンで別のプロジェクトを選択します。

## bqコマンド

```shell
# プロジェクトが定まらない場合は、クエリが実行できない。
$ bq query --use_legacy_sql=false 'SELECT * FROM `sandbox-suzutatsu-bq.test.sample1_20190103`'
BigQuery error in query operation: Cannot start a job without a project id.

# --project_id でプロジェクトを指定していたら、そのプロジェクトでクエリを実行する。
$ bq query --use_legacy_sql=false --project_id=sandbox-suzutatsu-bill 'SELECT * FROM `sandbox-suzutatsu-bq.test.sample1_20190103`'
BigQuery error in query operation: Access Denied: Project sandbox-suzutatsu-bill: User does not have bigquery.jobs.create permission in project
sandbox-suzutatsu-bill.

# gcloud config set project でプロジェクトを指定していたら、--project_id が無くてもそのプロジェクトでクエリを実行する。
$ gcloud config set project sandbox-suzutatsu-bill
$ bq query --use_legacy_sql=false 'SELECT * FROM `sandbox-suzutatsu-bq.test.sample1_20190103`'
BigQuery error in query operation: Access Denied: Project sandbox-suzutatsu-bill: User does not have bigquery.jobs.create permission in project
sandbox-suzutatsu-bill.


# あくまでデフォルトのプロジェクトを指定するだけなので、--project_id も指定していたら、そちらが優先される。
$ gcloud config set project sandbox-suzutatsu-bill
$ bq query --use_legacy_sql=false --project_id=sandbox-suzutatsu-bill2 'SELECT * FROM `sandbox-suzutatsu-bq.test.sample1_20190103`'
BigQuery error in query operation: Access Denied: Project sandbox-suzutatsu-bill2: User does not have bigquery.jobs.create permission in project
sandbox-suzutatsu-bill2.
```

※どのプロジェクトでクエリを実行したか分かるよう、上記では意図的に該当プロジェクトでクエリを実行する権限`bigquery.jobs.create`を外しています。

プロジェクトを切り替えるには、`bq`コマンドで`--project_id`を指定するか、`gcloud config set project`で`gcloud`コマンドのデフォルト値の設定を変更します。

## データポータル

データソースを作成する際に指定します。

### マイプロジェクトの場合

課金プロジェクトを指定する箇所がありません。
選択したプロジェクトが、クエリを実行するプロジェクトになります。
![スクリーンショット 2020-12-04 16.57.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/e9e6ce46-9c75-907f-fb7a-75c98871aa03.png)

### 共有プロジェクトの場合
課金プロジェクトを指定する設定があります。
ここで選択したプロジェクトが、クエリを実行するプロジェクトになります。
![スクリーンショット 2020-12-04 16.55.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/57455434-02bf-014b-677f-678ab17ba43f.png)

### カスタムクエリの場合
課金プロジェクトを指定する設定があります。
詳細オプションに課金プロジェクトIDをオーバーライドする欄があります。（便利さが分かってないのでどなたか教えてください）
![スクリーンショット 2020-12-04 17.00.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175280/6afdf601-da89-56c7-5f79-f2ec17916405.png)
プロジェクトを切り替えるには、データソース編集画面の課金プロジェクトで、別のプロジェクトを選択します。

# おわりに

今回はクエリ課金の視点でしたが、クエリを実行するプロジェクトは、クエリ実行権限にも関連する話です。
想定していなかった課金の発生だけでなく、クエリ実行権限エラーに遭遇した時にも、クエリを実行するプロジェクトがどれになっているか確認してみてください。