BigQuery の Short query optimized mode(短いクエリの最適化モード)を解説

記事タイトルとURLをコピーする

G-gen の杉村です。当記事では、BigQuery の Short query optimized mode(短いクエリの最適化モード)について解説します。

概要

Short query optimized mode とは

BigQuery の Short query optimized mode(短いクエリの最適化モード)とは、処理時間が短くて済むクエリを、より小さいレイテンシで実行するための機能です。

Short query optimized mode を有効化した状態でクエリを実行すると、BigQuery により最適化が可能かどうかが自動で判断され、可能な場合は最適化が適用されます。

データ探索時のクエリや、ダッシュボード等から実行される細かいクエリなどの際に、この最適化を用いることが想定されています。

BigQuery は通常、クエリをジョブという単位で非同期的に処理します。クエリを受け付けるとバックエンドでジョブが実行され、クライアントはジョブの実行結果を取得することで、処理結果を得ることができます。一方で Short query optimized mode 最適化が適用されると、ジョブが作成されず、クエリのリクエストに対するレスポンスに直接、実行結果が格納されます。

なお、当機能は2024年8月現在、Preview 段階であり、本番環境での利用は推奨されません。Preview 段階のサービスの注意点については、以下の記事もご参照ください。

blog.g-gen.co.jp

利用方法

Short query optimized mode は、BigQuery Studio(Web コンソール)、bq コマンドライン、各種プログラミング言語用のクライアントライブラリで利用できます。

BigQuery Studio(Web コンソール)からの利用

コンソール上での実行時、Short query optimized mode 最適化が適用されると、通常のジョブ実行クエリで表示されるジョブの各種情報(ジョブの開始・終了時刻、スロット秒、宛先テーブルなど)が表示されません。ジョブ ID も割り振られておらず、代わりにクエリ ID という一意の ID が表示されます。

ジョブ情報が表示されず、クエリ ID のみが表示される

各種言語用のクライアントライブラリで当機能を使う場合は、環境変数 QUERY_PREVIEW_ENABLED の値を TRUE にして実行します。

仕様

コンソール画面や bq コマンドライン、SDK などでのクエリ実行時に当モードを明示的に有効化すると、クエリ実行時に BigQuery が最適化の可否を自動的に判断し、可能であれば自動的に最適化されます。

最適化が適用されていない通常のクエリ実行では、クエリを実行するたびにジョブが生成され非同期に処理が行われますが、最適化が適用されると、ジョブが作成されません。その代わりに、クエリのリクエストに対するレスポンスに直接、実行結果が格納されます。

また通常のクエリ実行の API レスポンス body には jobReference という要素が含まれますが、最適化が適用された場合には、この要素が含まれません。

なお、最適化オプションを有効化した場合でも、キャッシュが利用できる場合は、通常クエリと同様に利用されます。

当モードの利用により、実際にどのくらいレイテンシが改善されるかについては、後述の検証結果で紹介します。

検証

確認する内容

当検証では、以下の2点を確認しました。

  • どのくらいのデータサイズまで Short query optimized mode が適用されるのか
  • Short query optimized mode が適用される場合、どのくらいレイテンシが短くなるのか

手順

まず、以下のような検証用テーブルを用意しました。

  • 10個のテーブル table_20240901table_20240910
  • 1テーブルあたり、100KB のデータ(STRING 型)を持つ

Short query optimized mode 適用有無の判断が読み取りバイト数に基づいて行われるものかどうかについてはドキュメントに明記がないものの、使用した実感から概ね相関関係があることが感じられましたので、徐々に読み取りバイト数を大きくしていき、Short query optimized mode が適用されるかどうかを確かめるという検証を行いました。

上記のテーブルに対して、Short query optimized mode を無効化した状態と有効化した状態で以下のようにクエリを実行していき、徐々に読み取りバイト数を増やします。なお、キャッシュが検証結果に影響を及ぼさないように、キャッシュ利用は無効化してクエリを実行します。

1回目

SELECT * FROM `my_dataset.table_20240901`

2回目

SELECT * FROM `my_dataset.table_20240901`
UNION ALL
SELECT * FROM `my_dataset.table_20240902`

このようにすることで、徐々に読み取りデータサイズを大きくし、どこまで Short query optimized mode が適用されるのかを確認することができます。これに加え、クエリを投入してから結果画面に表示するまでの時間、すなわち TAT(Turn Around Time)を計測することで、レイテンシの差を確認します。

測定方法

クエリを実行して TAT を測定する Python スクリプトを作成し、処理時間を計測します。以下はスクリプトの抜粋です。

client = bigquery.Client()
job_config = bigquery.QueryJobConfig(use_query_cache=False)
  
for query in queries:
    start_time = time.time()
    rows = client.query_and_wait(query, job_config=job_config)
    end_time = time.time()
  
    elapsed_time = end_time - start_time
  
    if rows.job_id is not None:
        print(f"{elapsed_time},job,{rows.job_id}")
    else:
        print(f"{elapsed_time},short,{rows.query_id}")

スクリプト実行時に、環境変数に QUERY_PREVIEW_ENABLED=TRUE を設定することで、Short query optimized mode を有効化した状態でクエリを実行できます。

QUERY_PREVIEW_ENABLED=TRUE python3 main.py

実行結果として、以下のような情報が出力されます(ヘッダーは当記事で補足)。

秒数 種類 ID
0.8255126476 Short ksfyv1Gt_Q2HMkrexxxxxxxxxxxxxxxxxxxx
0.5543231964 Short mmMlQzj-VoASi1ojxxxxxxxxxxxxxxxxxxxx
0.4366095066 Short 82CMY7aO0uFUrTabxxxxxxxxxxxxxxxxxxxx
0.4266831875 Short c8BTllBnFeDATkRWxxxxxxxxxxxxxxxxxxxx
0.4838123322 Short X5jTGTf6aDMoji_Cxxxxxxxxxxxxxxxxxxxx
1.988491535 Job job_hGHCmANAUBI4xxxxxxxxxxxxxxxx
1.436969995 Job job_MC_xpwSULvNGxxxxxxxxxxxxxxxx
1.454006195 Job job_Gf_WIobzP90Gxxxxxxxxxxxxxxxx
1.824844122 Job job_lApXaSSuCdRdxxxxxxxxxxxxxxxx
1.635432959 Job job_CB6e21vu_lLexxxxxxxxxxxxxxxx

QUERY_PREVIEW_ENABLED=TRUE を付与した実行結果と付与していない実行結果を比較して、レイテンシの比較を行います。use_query_cache=False を指定しているので、複数回実行してもキャッシュの影響はありません。

また追加の確認方法として、システムビューである INFORMATION_SCHEMA.JOBS から、以下のようなクエリで情報を取得します。

SELECT
 creation_time,
 user_email,
 job_id,
 job_creation_reason,
 statement_type,
 start_time,
 end_time,
 UNIX_MILLIS(end_time) - UNIX_MILLIS(start_time) AS elapsed_time,
 query,
 total_bytes_processed,
 total_slot_ms,
 total_bytes_billed
FROM
 `region-US`.INFORMATION_SCHEMA.JOBS
WHERE
 creation_time BETWEEN "<検証開始時刻>" AND "<検証終了時刻>"
 AND statement_type = "SELECT"
ORDER BY
 creation_time

同システムビューは、BigQuery に対して実行されたジョブやクエリがすべて記録されるビューです。同ビューの job_creation_reason.code 列を見ると、ジョブの性質を確認することができます。

job_creation_reason.code 列の値 意味
NULL Short query optimized mode が有効化された状態で実行され、 最適化が適用されたクエリ
LARGE_RESULTS Short query optimized mode が有効化された状態で実行されたが、 最適化が適用されなかったクエリ
REQUESTED 通常実行のクエリ

INFORMATION_SCHEMA.JOBS ビュー

また job_id 列の値は、以下のようになります。

job_id 列の値 意味
(ランダムな英数字) Short query optimized mode の最適化が適用されたクエリのクエリ ID
bquxjob_(ランダムな英数字)
または
job_(ランダムな英数字)
ジョブで実行されたクエリのジョブ ID

これらを参考に、クエリに最適化が適用されたかどうかを判別することができます。

また start_time 列と end_time 列の差を見ることで、BigQuery の内部処理の実行時間(ネットワークやローカル PC での処理を含まない、BigQuery の処理実行時間)を確認できます。

結果と考察

データサイズごとの最適化適用有無

100 KBずつ読み取りデータ量を増やしていき、どこまで Short query optimized mode 最適化が適用されるかを確認しました。

読み取りデータ量 Short query 最適化
100 KB TRUE
200 KB TRUE
300 KB TRUE
400 KB TRUE
500 KB TRUE
600 KB FALSE
700 KB FALSE
800 KB FALSE
900 KB FALSE
1000 KB FALSE

500 KB の読み取りまでは Short query optimized mode 最適化が適用されました。

今回は無作為な文字列データを用いましたが、別のデータセット(当社ウェブサイトの Google Analytics 4 データ)で検証したところ、概ね 450 KB 程度を境界に Short query optimized mode 最適化がされなくなりました。このことから、適用有無の判断には、単純にデータサイズだけではなく複数の要素が用いられていると考えられます。

TAT と BigQuery 内部処理時間

Python スクリプトによって測定した、通常のジョブとしてクエリを実行したときと Short query optimized mode 最適化が適用されたときの TAT の違いは、以下のとおりでした。

読み取りデータ量 ジョブ Short query 差異
100 KB 1175 ms 826 ms 350 ms
200 KB 747 ms 554 ms 193 ms
300 KB 790 ms 437 ms 353 ms
400 KB 717 ms 427 ms 291 ms
500 KB 735 ms 484 ms 251 ms
600 KB 1346 ms N/A N/A
700 KB 1404 ms N/A N/A
800 KB 1532 ms N/A N/A
900 KB 1537 ms N/A N/A
1000 KB 1638 ms N/A N/A

概ね200〜350 ms の違いが出ています。

INFORMATION_SCHEMA.JOBS システムビューから測定した、BigQuery の内部処理時間の差は、以下の通りでした。

読み取りデータ量 ジョブ Short query 差異
100 KB 228 ms 120 ms 108 ms
200 KB 234 ms 132 ms 102 ms
300 KB 252 ms 142 ms 110 ms
400 KB 232 ms 142 ms 90 ms
500 KB 283 ms 163 ms 120 ms
600 KB 828 ms N/A N/A
700 KB 846 ms N/A N/A
800 KB 985 ms N/A N/A
900 KB 957 ms N/A N/A
1000 KB 939 ms N/A N/A

およそ 100 ms 程度の差異が出ています。これは、前掲の TAT における数値とは差があります。

TAT には、BigQuery の内部処理時間だけでなく、ジョブ投入後に結果を取得する処理のオーバーヘッドも含まれていると考えられます。通常のクエリですと「ジョブ投入後に待機し、ジョブ結果を取得する」という非同期的処理を行いますが、Short query 最適化が適用されると、「クエリを投入すると、直ちに結果が返ってくる」という同期的処理になるため、その分、処理時間が短くなったと考えられます。

杉村 勇馬 (記事一覧)

執行役員 CTO / クラウドソリューション部 部長

元警察官という経歴を持つ現 IT エンジニア。クラウド管理・運用やネットワークに知見。AWS 12資格、Google Cloud認定資格11資格。X (旧 Twitter) では Google Cloud や AWS のアップデート情報をつぶやいています。