BigQueryでクエリの費用やスロット利用量を確認するために、 JOBS_BY_***
を活用することが多いです。
しかし、CREATE TEMP TABLEを含むクエリの費用を計算するときには注意が必要です。
例えば、以下のクエリを実行するとします。
CREATE TEMP TABLE hoge AS (......);
CREATE TEMP TABLE fuga AS (......);
SELECT ... FROM hoge JOIN ......;
この時、 JOBS_BY_***
には以下の4行が記録されます。
job_id | parent_job_id | statement_type | total_bytes_billed | query |
---|---|---|---|---|
<乱数 or ジョブの作成時に指定したID> ※① | NULL | SCRIPT | <以下の3つの数値の合計> | SQLの全文 |
script_<乱数> | ① | CREATE_TABLE_AS_SELECT | 1つ目のCREATE TEMPでスキャンされたデータ量 | CREATE TEMP TABLE hoge AS (......) |
script_<乱数> | ① | CREATE_TABLE_AS_SELECT | 2つ目のCREATE TEMPでスキャンされたデータ量 | CREATE TEMP TABLE fuga AS (......); |
script_<乱数> | ① | SELECT | 最終行のSELECTでスキャンされたデータ量 | SELECT ... FROM hoge JOIN ......; |
最初のstatement_typeがSCRIPTな行はSQLの実行全体に関する情報を提供しています。
この行のtotal_bytes_billedは2つのCREATE TEMP TABLEと最後のSELECEでスキャンされたデータ量の合計になります。
その後の3行は個別のSQL文の実行に関する情報を提供しています。
このような記録の仕方をしているため、単純に SUM(total_bytes_billed)
を行ってクエリの実行費用を出すと、二重にカウントされることになります。
そのため WHERE statement_type <> 'SCRIPT'
のようなWHERE句を追加して二重にカウントを避ける必要があります。
なお、この挙動はtotal_bytes_billedだけではなく、total_slot_msなどの他の指標についても同様です。