クエリに関する問題のトラブルシューティング

このドキュメントでは、クエリの実行に関連する一般的な問題(低速なクエリの理由の特定、失敗したクエリによって返される一般的なエラーの解決手順など)のトラブルシューティングに役立つ情報を提供します。

低速なクエリのトラブルシューティング

クエリのパフォーマンスが低い場合のトラブルシューティングでは、次の一般的な原因を検討してください。

  1. Google Cloud Service Health ページで、クエリのパフォーマンスに影響する可能性がある既知の BigQuery サービス停止を確認します。

  2. ジョブの詳細ページでクエリのジョブのタイムラインを確認し、クエリの各ステージの実行時間を確認します。

    • 経過時間のほとんどが長い作成時間によるものである場合は、Cloud カスタマーケアにお問い合わせください。

    • 経過時間のほとんどが長い実行時間によるものである場合は、クエリのパフォーマンス分析情報を確認します。クエリのパフォーマンス分析情報では、クエリの実行時間が平均実行時間を超えた場合に、考えられる原因が示されます。原因として、クエリスロットの競合やシャッフル割り当ての不足が考えられます。各クエリのパフォーマンスの問題とその解決策の詳細については、クエリのパフォーマンス分析情報を解釈するをご覧ください。

  3. クエリジョブの JobStatisticsfinalExecutionDurationMs フィールドを確認します。クエリが再試行された可能性があります。finalExecutionDurationMs フィールドには、このジョブの最終試行の実行時間(ミリ秒単位)が含まれます。

  4. クエリジョブの詳細ページで処理されたバイト数を確認し、予想よりも大きいかどうかを確認します。これを行うには、現在のクエリによって処理されたバイト数を、許容可能な時間内に完了した別のクエリジョブと比較します。2 つのクエリで処理されたバイト数に大きな差異がある場合は、データ量が多いためにクエリが低速になった可能性があります。大規模なデータ量を処理するようにクエリを最適化する方法については、クエリ計算を最適化するをご覧ください。

    INFORMATION_SCHEMA.JOBS ビューを使用して最も費用のかかるクエリを検索することで、大量のデータを処理するプロジェクト内のクエリを特定することもできます。

同じクエリの遅い実行と速い実行を比較する

以前は高速で実行されていたクエリが遅くなった場合は、Job API オブジェクトの出力を調べて、実行の変更を特定します。

キャッシュ ヒット

cacheHit の値を確認して、ジョブの高速実行がキャッシュ ヒットであったかどうかを確認します。クエリの高速実行の値が true の場合、クエリは実行されず、キャッシュに保存された結果が使用されました。

ジョブが遅い場合にキャッシュに保存された結果を使用すると予想される場合は、クエリがキャッシュに保存された結果を使用しなくなった理由を調べます。クエリがキャッシュからデータを取得しない場合は、キャッシュにヒットしなかった高速クエリ実行の例を探して調査します。

割り当ての遅延

遅延が割り当ての延期によって発生したかどうかを確認するには、両方のジョブの quotaDeferments フィールドを確認します。値を比較して、高速なジョブに影響しなかった割り当ての延期によって、低速なクエリの開始時間が遅延したかどうかを判断します。

実行時間

両方のジョブの最後の試行の実行時間の違いを把握するには、finalExecutionDurationMs フィールドの値を比較します。

finalExecutionDurationMs の値が非常に類似しているにもかかわらず、2 つのクエリ間の壁時計実行時間の差(startTime - endTime として計算)がはるかに大きい場合は、一時的な問題が原因で、低速ジョブの内部クエリ実行が再試行された可能性があります。この差異パターンが繰り返し表示される場合は、Cloud カスタマーケアにお問い合わせください

処理されたバイト数

クエリジョブの詳細ページで処理されたバイト数を確認するか、JobStatisticstotalBytesProcessed を確認して、予想よりも大きいかどうかを確認します。2 つのクエリで処理されたバイト数に大きな差異がある場合は、処理されたデータ量の変化が原因でクエリが低速になった可能性があります。大規模なデータ量を処理するようにクエリを最適化する方法については、クエリ計算を最適化するをご覧ください。クエリで処理されるバイト数が増加する原因として、次の理由が考えられます。

  • クエリで参照されるテーブルのサイズが増加しました。
  • クエリがテーブルのより大きなパーティションを読み取るようになりました。
  • クエリが、定義が変更されたビューを参照している。

参照されるテーブル

JobStatistics2referencedTables フィールドの出力を分析して、クエリが同じテーブルを読み取っているかどうかを確認します。参照テーブルの違いは、次の理由で説明できます。

  • SQL クエリが変更され、別のテーブルを読み取るようになりました。クエリテキストを比較して確認します。
  • クエリの実行間にビュー定義が変更されました。このクエリで参照されているビューの定義を確認し、必要に応じて更新します。

参照先テーブルの違いは、totalBytesProcessed の変化を説明する可能性があります。

マテリアライズド ビューの使用状況

クエリがマテリアライズド ビューを参照している場合、クエリの実行中にマテリアライズド ビューが選択または拒否されると、パフォーマンスに違いが生じることがあります。MaterializedViewStatistics を調べて、高速クエリで使用されたマテリアライズド ビューが低速クエリで拒否されたかどうかを確認します。MaterializedView オブジェクトchosen フィールドと rejectedReason フィールドを確認します。

メタデータのキャッシュ保存の統計情報

メタデータ キャッシュが有効になっている Amazon S3 BigLake テーブルまたは Cloud Storage BigLake テーブルを含むクエリの場合は、MetadataCacheStatistics の出力を比較して、遅いクエリと速いクエリのメタデータ キャッシュの使用状況に違いがあるかどうかと、その理由を確認します。たとえば、メタデータ キャッシュがテーブルの maxStaleness ウィンドウの外にある可能性があります。

BigQuery BI Engine の統計情報を比較する

クエリで BigQuery BI Engine を使用している場合は、BiEngineStatistics の出力を分析して、遅いクエリと速いクエリの両方に同じ高速化モードが適用されているかどうかを確認します。BiEngineReason フィールドを見ると、メモリ不足、予約の欠落、入力が大きすぎるなど、部分的な高速化または高速化なしの理由を大まかに把握できます。

クエリのパフォーマンス分析情報の違いを確認する

Google Cloud コンソールの実行グラフまたは StagePerformanceStandaloneInsight オブジェクトを確認して、各クエリのクエリ パフォーマンス分析情報を比較し、次の問題の可能性を把握します。

パフォーマンスに影響するステージの変更を特定するには、遅いジョブの分析情報と、速いジョブの分析情報の違いの両方に注意してください。

ジョブ実行メタデータのより詳細な分析を行うには、2 つのジョブの ExplainQueryStage オブジェクトを比較して、クエリ実行の単一ステージを調べる必要があります。

まず、クエリ ステージ情報を解釈するセクションで説明されている Wait ms 指標と Shuffle output bytes 指標を確認します。

INFORMATION_SCHEMA.JOBS ビューのリソース警告

INFORMATION_SCHEMA.JOBS ビューquery_info.resource_warning フィールドをクエリして、使用されているリソースに関して BigQuery で分析された警告に違いがあるかどうかを確認します。

ワークロードの統計情報の分析

利用可能なスロットリソースとスロット競合は、クエリの実行時間に影響する可能性があります。以降のセクションでは、クエリの特定の実行におけるスロットの使用状況と可用性を確認する方法について説明します。

1 秒あたりの平均スロット数

クエリが使用したミリ秒あたりの平均スロット数を計算するには、ジョブのスロットミリ秒値(JobStatistics2totalSlotMs)を、このジョブの最終試行の実行時間(ミリ秒単位)(JobStatisticsfinalExecutionDurationMs)で割ります。

INFORMATION_SCHEMA.JOBS ビューに対してクエリを実行して、ジョブが使用したミリ秒あたりの平均スロット数を計算することもできます。

1 秒あたりの平均スロット数が多いほど、同様の作業を行うジョブの完了が速くなります。1 秒あたりの平均スロット使用量が少ない場合は、次の原因が考えられます。

  1. 異なるジョブ間のリソース競合により、追加のリソースが使用できませんでした。予約が上限に達しました。
  2. ジョブは実行の大部分でスロットをリクエストしませんでした。たとえば、データスキューがある場合に発生することがあります。

ワークロード管理モデルと予約サイズ

オンデマンドの課金モデルを使用する場合、プロジェクトごとに使用できるスロットの数には上限があります。また、特定のロケーションでのオンデマンド容量に対して大量の競合が発生している場合、利用可能なスロットが少なくなることがあります。

容量ベースのモデルは予測しやすく、保証されるベースライン スロット数を指定できます。

オンデマンドを使用して実行されたクエリ実行と予約を使用するクエリ実行を比較する場合は、これらの違いを考慮してください。

安定した予測可能なクエリ実行パフォーマンスを実現するには、予約を使用することをおすすめします。オンデマンド ワークロードと容量ベースのワークロードの違いについては、ワークロード管理の概要をご覧ください。

ジョブの同時実行

ジョブの同時実行は、クエリ実行中のスロット リソースに対するジョブ間の競合を表します。一般的に、ジョブの同時実行性が高いほど、ジョブがアクセスできるスロットが少なくなるため、ジョブの実行速度が遅くなります。

INFORMATION_SCHEMA.JOBS ビューに対してクエリを実行すると、プロジェクト内の特定のクエリと同時に実行されている同時実行ジョブの平均数を確認できます。

予約に複数のプロジェクトが割り当てられている場合は、JOBS_BY_PROJECT ではなく JOBS_BY_ORGANIZATION を使用するようにクエリを変更して、予約レベルのデータを正確に取得します。

遅いジョブの実行中の平均同時実行数が速いジョブよりも多い場合は、全体的な遅延の原因となります。

リソースを大量に消費するクエリを、1 つの予約またはプロジェクト内でさまざまな時間に分散させるか、複数の予約またはプロジェクトに分散させることで、プロジェクトまたは予約内の同時実行数を減らすことを検討してください。

別の解決策として、予約を購入するか、既存の予約のサイズを増やすこともできます。予約でアイドル スロットを使用することを検討してください。

追加するスロットの数を把握するには、スロットの容量要件の見積もりをご覧ください。

複数のプロジェクトが割り当てられている予約で実行されているジョブでは、同じ平均ジョブ同時実行数でも、実行するプロジェクトによってスロット割り当ての結果が異なる場合があります。詳しくは、フェア スケジューリングをご覧ください。

予約の使用率

管理リソースグラフBigQuery Cloud Monitoring を使用して、予約の使用率をモニタリングできます。詳細については、BigQuery の予約をモニタリングするをご覧ください。

ジョブが追加のスロットをリクエストしたかどうかを確認するには、推定実行可能ユニット指標(Job API レスポンスの estimatedRunnableUnits、または INFORMATION_SCHEMA.JOBS_TIMELINE ビューperiod_estimated_runnable_units)を確認します。この指標の値が 0 より大きい場合、その時点でジョブに追加のスロットを割り当てると、ジョブのパフォーマンスが向上する可能性があります。ジョブが追加のスロットの恩恵を受けるジョブ実行時間の割合を見積もるには、INFORMATION_SCHEMA.JOBS_TIMELINE ビューに対して次のクエリを実行します。

SELECT
  ROUND(COUNTIF(period_estimated_runnable_units > 0) / COUNT(*) * 100, 1) AS execution_duration_percentage
FROM `myproject`.`region-us`.INFORMATION_SCHEMA.JOBS_TIMELINE
WHERE job_id = 'my_job_id'
GROUP BY job_id;
次のような結果になります。
+---------------------------------+
|   execution_duration_percentage |
+---------------------------------+
|                            96.7 |
+---------------------------------+

割合が低い場合は、このシナリオではスロット リソースの可用性がクエリの遅延の主な原因ではないことを意味します。

この割合が高く、この期間中に予約が完全に利用されていない場合は、Cloud カスタマーケアにお問い合わせください。

ジョブの実行が遅いときに予約が完全に利用され、割合が高い場合は、ジョブがリソースで制約されています。同時実行数を減らすか、予約サイズを増やすか、予約でアイドル状態のスロットを使用できるようにするか、ジョブがオンデマンドで実行された場合は予約を購入することを検討してください。

ジョブ メタデータとワークロード分析の結果が不確実

それでも、想定よりも低速なクエリのパフォーマンスを説明する理由が見つからない場合は、Cloud カスタマーケアにお問い合わせください。

gcpdiag を使用してクエリの失敗をトラブルシューティングする

gcpdiag はオープンソース ツールです。正式にサポートされている Google Cloud プロダクトではありません。gcpdiag ツールを使用すると、 Google Cloudプロジェクトの問題を特定して修正できます。詳細については、GitHub の gcpdiag プロジェクトをご覧ください。

gcpdiag ツールは、失敗した BigQuery クエリを分析して、特定の障害の既知の根本原因と軽減策があるかどうかを把握するのに役立ちます。

gcpdiag コマンドを実行する

gcpdiag コマンドは、Google Cloud CLI から実行できます。

Google Cloud コンソール

  1. 次のコマンドを入力してコピーします。
  2. gcpdiag runbook bigquery/failed_query \
       --parameter project_id=PROJECT_ID \
       --parameter bigquery_job_region=JOB_REGION \
       --parameter bigquery_job_id=JOB_ID \
       --parameter bigquery_skip_permission_check=SKIP_PERMISSION_CHECK
  3. Google Cloud コンソールを開き、Cloud Shell を有効にします。
  4. Cloud コンソールを開く
  5. コピーしたコマンドを貼り付けます。
  6. gcpdiag コマンドを実行します。gcpdiag Docker イメージがダウンロードされ、診断チェックが実行されます。必要に応じて、出力の指示に沿って、失敗したチェックを修正します。

Docker

Docker コンテナで gcpdiag を起動するラッパーを使用して gcpdiag を実行できます。Docker または Podman がインストールされている必要があります。

  1. ローカル ワークステーションで次のコマンドをコピーして実行します。
    curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag && chmod +x gcpdiag
  2. gcpdiag コマンドを実行します。
    ./gcpdiag runbook bigquery/failed_query \
       --parameter project_id=PROJECT_ID \
       --parameter bigquery_job_region=JOB_REGION \
       --parameter bigquery_job_id=JOB_ID \
       --parameter bigquery_skip_permission_check=SKIP_PERMISSION_CHECK

このランブックで使用可能なパラメータを表示します。

次のように置き換えます。

  • PROJECT_ID: リソースを含むプロジェクトの ID。
  • JOB_REGION: BigQuery ジョブが実行されたリージョン。
  • JOB_ID: BigQuery ジョブのジョブ ID。
  • SKIP_PERMISSION_CHECK: (省略可)関連する権限チェックをスキップして、ランブックの実行を高速化する場合は、これを True に設定します(デフォルト値は False)。

有用なフラグ:

gcpdiag ツールのフラグの一覧と説明については、gcpdiag の使用手順をご覧ください。

Avro のスキーマ解決

エラー文字列: Cannot skip stream

このエラーは、スキーマが異なる複数の Avro ファイルを読み込むときに発生する可能性があります。その結果、スキーマ解決に関する問題が発生し、インポート ジョブがランダムなファイルで失敗します。

このエラーに対処するには、読み込みジョブの最後のアルファベット ファイルに、異なるスキーマのスーパーセット(ユニオン)が含まれていることを確認してください。これは、Avro がスキーマ解決を処理する仕組みに基づく要件です。

同時実行クエリの競合

エラー文字列: Concurrent jobs in the same session are not allowed

このエラーは、複数のクエリがセッションで同時に実行されている場合に発生する可能性があります。複数クエリの同時実行はサポートされていません。セッションの制限事項をご覧ください。

DML ステートメントの競合

エラー文字列: Could not serialize access to table due to concurrent update

このエラーは、同じテーブルに対して同時に実行されている変更データ操作言語(DML)ステートメントが互いに競合する場合、または変更 DML ステートメントの実行中にテーブルが切り捨てられる場合に発生することがあります。詳細については、DML ステートメントの競合をご覧ください。

このエラーに対処するには、DML オペレーションが重複しないように、1 つのテーブルに影響する DML オペレーションを実行します。

相関サブクエリ

エラー文字列: Correlated subqueries that reference other tables are not supported unless they can be de-correlated

このエラーは、クエリに、そのサブクエリの外部から列を参照するサブクエリ(相関列)が含まれている場合に発生することがあります。相関サブクエリは、効率が悪いネストされた実行戦略を使用して評価されます。この戦略では、相関列を生成する外部クエリの行ごとにサブクエリが評価されます。BigQuery では、関連するサブクエリを使用してクエリを内部的に書き換えることで、より効率的に実行できる場合があります。相関サブクエリのエラーは、BigQuery でクエリを十分に最適化できない場合に発生します。

このエラーに対処するには、次の方法をお試しください。

  • サブクエリから ORDER BYLIMITEXISTSNOT EXISTSIN の句を削除します。
  • マルチステートメント クエリを使用して、サブクエリで参照する一時テーブルを作成します。
  • 代わりに CROSS JOIN を使用するようにクエリを書き換えます。

列レベルのアクセス制御の権限が不十分

エラー文字列: Requires fineGrainedGet permission on the read columns to execute the DML statements

このエラーは、スキャンする列に対し、列レベルのアクセス制御を使用して列レベルでアクセスを制限するきめ細かい読み取り権限がない状態で、DELETEUPDATEMERGE の DML ステートメントを試行した場合に発生します。詳細については、列レベルのアクセス制御からの書き込みへの影響をご覧ください。

スケジュールされたクエリの認証情報が無効

エラー文字列:

  • Error code: INVALID_USERID
  • Error code 5: Authentication failure: User Id not found
  • PERMISSION_DENIED: BigQuery: Permission denied while getting Drive credentials

このエラーは、特に Google ドライブのデータに対してクエリを実行するときなど、古い認証情報が原因でスケジュールされたクエリが失敗した場合に発生する可能性があります。

このエラーに対処するには、次の手順をお試しください。

サービス アカウントの認証情報が無効

エラー文字列: HttpError 403 when requesting returned: The caller does not have permission

このエラーは、サービス アカウントを使用してスケジュールされたクエリを設定しようとすると表示されることがあります。このエラーを解決するには、認証と権限に関する問題のトラブルシューティング手順をご覧ください。

スナップショット時間が無効

エラー文字列: Invalid snapshot time

このエラーは、データセットのタイムトラベル期間外の過去のデータをクエリしようとすると発生することがあります。このエラーに対処するには、データセットのタイムトラベル期間内の過去のデータにアクセスするようにクエリを変更します。

このエラーは、クエリで使用されているテーブルのいずれかが削除され、クエリの開始後に再作成された場合にも発生することがあります。失敗したクエリと同時に実行されていたこのオペレーションを実行するスケジュールされたクエリまたはアプリケーションがあるかどうかを確認します。ある場合は、削除と再作成のオペレーションを実行するプロセスを、そのテーブルを読み取るクエリと競合しない時間に実行してみてください。

ジョブがすでに存在している

エラー文字列: Already Exists: Job <job name>

このエラーは、大規模な配列を評価する必要があり、作成に平均よりも時間がかかるクエリジョブで発生する可能性があります。たとえば、WHERE column IN (<2000+ elements array>) のような WHERE 句を含むクエリなどです。

このエラーに対処するには、次の手順をお試しください。

このエラーは、ジョブ ID を手動で設定したものの、ジョブがタイムアウト時間内に成功を返さなかった場合にも発生することがあります。この場合は、例外ハンドラを追加して、ジョブが存在するかどうかを確認できます。この場合、ジョブからクエリ結果を取得できます。

ジョブが見つからない

エラー文字列: Job not found

このエラーは、location フィールドに値が指定されていない getQueryResults 呼び出しが原因で発生することがあります。その場合は、location 値を指定して呼び出しを再試行します。

詳細については、同じ共通テーブル式(CTE)を複数回評価することを避けるをご覧ください。

ロケーションが見つからない

エラー文字列: Dataset [project_id]:[dataset_id] was not found in location [region]

このエラーは、存在しないデータセット リソースを参照した場合、またはリクエストのロケーションがデータセットのロケーションと一致しない場合に返されます。

この問題に対処するには、クエリでデータセットのロケーションを指定するか、データセットが同じロケーションで使用可能であることを確認します。

クエリの実行時間が上限を超えている

エラー文字列: Query fails due to reaching the execution time limit

クエリがクエリ実行時間の上限に達している場合は、次のようなクエリで INFORMATION_SCHEMA.JOBS ビューをクエリして、以前のクエリの実行時間を確認します。

SELECT TIMESTAMP_DIFF(end_time, start_time, SECOND) AS runtime_in_seconds
FROM `region-us`.INFORMATION_SCHEMA.JOBS
WHERE statement_type = 'QUERY'
AND query = "my query string";

以前のクエリの実行時間が大幅に短い場合は、クエリ パフォーマンスの分析情報を使用して、根本的な原因を特定し、対処します。

クエリのレスポンスが大きすぎる

エラー文字列: responseTooLarge

このエラーは、クエリの結果が最大レスポンス サイズよりも大きいときに返されます。

このエラーに対処するには、エラー テーブルresponseTooLarge エラー メッセージのガイダンスに従ってください。

予約が見つからないか、スロットがありません

エラー文字列: Cannot run query: project does not have the reservation in the data region or no slots are configured

このエラーは、クエリのリージョン内のプロジェクトに割り当てられた予約に割り当てられたスロットがない場合に発生します。予約にスロットを追加するか、予約でアイドル スロットを使用できるようにするか、別の予約を使用するか、割り当てを削除してクエリをオンデマンドで実行できます。

表が見つかりません

エラー文字列: Not found: Table [project_id]:[dataset].[table_name] was not found in location [region]

指定したデータセットまたは範囲に、クエリで指定したテーブルが見つからないと、このエラーが発生します。このエラーに対処するための操作は次のとおりです。

  • 正しいプロジェクト名、データセット名、テーブル名をクエリで指定していることを確認します。
  • クエリを実行した範囲にテーブルが存在することを確認します。
  • ジョブの実行中にテーブルが削除され、再作成されていないことを確認します。上記以外にも、メタデータの伝播が不完全であると、このエラーが発生することが考えられます。

DML ステートメントが多すぎる

エラー文字列: Too many DML statements outstanding against <table-name>, limit is 20

このエラーは、単一テーブルのキューで、PENDING ステータスの DML ステートメントの上限(20 個)を超えた場合に発生します。このエラーは通常、単一テーブルに対して BigQuery で処理できるより速度も速く DML ジョブを送信したときに発生します。

解決策としては、更新や挿入をバッチ処理するなどして、複数の小規模な DML オペレーションを、大規模で少ない数のジョブにグループ化することが考えられます。小さいジョブをより大きなジョブにグループ化すると、大規模なジョブを実行するためのコストは平均化され、実行は速くなります。同じデータに影響する DML ステートメントを統合すると、通常は DML ジョブの効率が向上し、キューサイズの割り当て上限を超える可能性が低くなります。DML オペレーションの最適化の詳細については、単一行を更新または挿入する DML ステートメントを避けるをご覧ください。

DML 効率を改善する別の解決策として、テーブルをパーティション分割またはクラスタ化することもできます。詳しくは、ベスト プラクティスをご覧ください。

同時に更新されたため、トランザクションが中止されました

エラー文字列: Transaction is aborted due to concurrent update against table [table_name]

2 つの異なる変更 DML ステートメントで同じテーブルを同時に更新しようとすると、このエラーが発生することがあります。たとえば、実行するとエラーが発生する変更 DML ステートメントがあるセッションでトランザクションを開始するとします。例外ハンドラがない場合、セッションの終了時に BigQuery によってこのトランザクションが自動的にロールバックされますが、それまでに最大で 24 時間を要します。それまでの間に、テーブルに対して変更 DML ステートメントを実行しようとすると失敗します。

このエラーに対処するには、アクティブなセッションを洗い出し、そのいずれかに、テーブルに対して変更 DML ステートメントを実行してステータスが ERROR になっているクエリジョブがないか確認します。そのようなセッションがあれば、それを終了します。

ユーザーに権限がない

エラー文字列:

  • Access Denied: Project [project_id]: User does not have bigquery.jobs.create permission in project [project_id].
  • User does not have permission to query table project-id:dataset.table.
  • Access Denied: User does not have permission to query table or perhaps it does not exist.

これらのエラーは、クエリを実行するプロジェクトに bigquery.jobs.create 権限がない状態でクエリを実行した場合に発生します。データを含むプロジェクトに対する権限に関係なく、このエラーが発生する可能性があります。

クエリで参照するすべてのテーブルとビューに対する bigquery.tables.getData 権限がサービス アカウント、ユーザー、グループにない場合にも、これらのエラーが発生することがあります。クエリの実行に必要な権限の詳細については、必要なロールをご覧ください。

また、クエリされたリージョン(asia-south1 など)に、テーブルが存在しない場合にも、これらのエラーが発生することがあります。リージョンを確認するには、データセットのロケーションを調べます。

これらのエラーに対処する際は、次の点に注意してください。

  • サービス アカウント: サービス アカウントには、実行するプロジェクトに対する bigquery.jobs.create 権限が必要です。また、クエリで参照されるすべてのテーブルとビューに対する bigquery.tables.getData 権限が必要です。

  • カスタムロール: IAM カスタムロールには、関連するロールに bigquery.jobs.create 権限が明示的に含まれている必要があります。また、クエリで参照されるすべてのテーブルとビューに対する bigquery.tables.getData 権限が必要です。

  • 共有データセット: 別のプロジェクトで共有データセットを操作する場合、そのデータセットでクエリやジョブを実行するには、プロジェクトの bigquery.jobs.create 権限が必要になる場合があります。

テーブルまたはビューへのアクセス権を付与するには、テーブルまたはビューへのアクセス権を付与するをご覧ください。

組織のポリシーによってアクセスが拒否されました

エラー文字列: IAM setPolicy failed for Dataset DATASET: Operation denied by org policy on resource.

このエラーは、組織のポリシーによってプリンシパルが BigQuery リソースをクエリできない場合に発生します。組織ポリシー サービスを使用すると、組織の階層全体で対応しているリソースに対して制約を適用できます。

プリンシパルがリソースにアクセスできる必要がある場合は、使用可能な VPC トラブルシューティング ツールを使用して、組織のポリシーの問題を診断する必要があります。

リソース超過の問題

クエリを完了するためのリソースが不足していると、次の問題が発生します。

クエリで CPU リソースの超過が発生する

エラー文字列: Query exceeded resource limits

このエラーは、スキャンされたデータの量と比べてオンデマンド クエリが使用する CPU が多すぎる場合に発生します。この問題を解決する方法については、リソース超過に関する問題のトラブルシューティングをご覧ください。

クエリでメモリリソースの超過が発生する

エラー文字列: Resources exceeded during query execution: The query could not be executed in the allotted memory

SELECT ステートメントの場合、このエラーはクエリで使用するリソースが多すぎる場合に発生します。このエラーに対処するには、リソース超過に関する問題のトラブルシューティングをご覧ください。

スタック領域の不足

エラー文字列: Out of stack space due to deeply nested query expression during query resolution.

このエラーは、クエリにネストされた関数呼び出しが多すぎる場合に発生することがあります。クエリの一部は、解析中に関数呼び出しに変換されることがあります。たとえば、A || B || C || ... のように、連結演算子が繰り返される式は CONCAT(A, CONCAT(B, CONCAT(C, ...))) になります。

このエラーに対処するには、クエリを書き換えてネストの量を減らします。

クエリ実行中のリソース超過

エラー文字列: Resources exceeded during query execution: The query could not be executed in the allotted memory. Peak usage: [percentage]% of limit. Top memory consumer(s): ORDER BY operations.

これは ORDER BY ... LIMIT ... OFFSET ... クエリで発生する可能性があります。実装の詳細により、並べ替えは単一のコンピューティング ユニットで行われることがあります。LIMITOFFSET が適用される前に処理する行が多すぎると(特に OFFSET が大きい場合)、メモリ不足になる可能性があります。

このエラーに対処するには、ORDER BY ... LIMIT クエリで大きな OFFSET 値を使用しないようにします。または、スケーラブルな ROW_NUMBER() ウィンドウ関数を使用して、選択した順序に基づいてランクを割り当て、これらのランクを WHERE 句でフィルタします。例:

SELECT ...
FROM (
  SELECT ROW_NUMBER() OVER (ORDER BY ...) AS rn
  FROM ...
)
WHERE rn > @start_index AND rn <= @page_size + @start_index  -- note that row_number() starts with 1

クエリでシャッフル リソースの超過が発生する

エラー文字列: Resources exceeded during query execution: Your project or organization exceeded the maximum disk and memory limit available for shuffle operations

このエラーは、クエリが十分なシャッフル リソースにアクセスできない場合に発生します。

このエラーに対処するには、より多くのスロットをプロビジョニングするか、クエリで処理するデータの量を減らします。この方法の詳細については、シャッフル割り当てが不十分をご覧ください。

この問題を解決する方法の詳細については、リソース超過に関する問題のトラブルシューティングをご覧ください。

クエリが複雑すぎる

エラー文字列: Resources exceeded during query execution: Not enough resources for query planning - too many subqueries or query is too complex

このエラーは、クエリが複雑すぎる場合に発生します。複雑になる主な原因は次のとおりです。

  • WITH 句が深くネストしているか、繰り返し使用されている。
  • ビューが深くネストしているか、繰り返し使用されている。
  • UNION ALL 演算子が繰り返し使用されている。

このエラーに対処するには、次の方法をお試しください。

  • クエリを複数のクエリに分割し、手続き型言語を使用して、共有状態でこれらのクエリを順番に実行します。
  • WITH 句ではなく一時テーブルを使用します。
  • クエリを書き換えて、参照されるオブジェクトと比較の数を減らします。

INFORMATION_SCHEMA.JOBS ビューquery_info.resource_warning フィールドを使用すると、複雑さの上限に近づいているクエリを事前にモニタリングできます。次の例は、過去 3 日間のリソース使用率が高いクエリを返します。

SELECT
  ANY_VALUE(query) AS query,
  MAX(query_info.resource_warning) AS resource_warning
FROM
  <your_project_id>.`region-us`.INFORMATION_SCHEMA.JOBS
WHERE
  creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 3 DAY)
  AND query_info.resource_warning IS NOT NULL
GROUP BY
  query_info.query_hashes.normalized_literals
LIMIT
  1000

この問題を解決する方法の詳細については、リソース超過に関する問題のトラブルシューティングをご覧ください。

リソース超過に関する問題のトラブルシューティング

クエリジョブの場合:

クエリを最適化するために、次の手順をお試しください。

  • ORDER BY 句を削除します。
  • クエリで JOIN を使用している場合は、サイズが大きいほうのテーブルを句の左側に指定します。また、データに重複する結合キーが含まれていないことを確認してください。
  • クエリで FLATTEN を使用している場合は、そのユースケースでこれが必要かどうかを判断します。詳しくは、ネストされたデータと繰り返しデータをご覧ください。
  • クエリで EXACT_COUNT_DISTINCT を使用している場合は、COUNT(DISTINCT) の使用を検討してください。
  • クエリで使用している COUNT(DISTINCT <value>, <n>)<n> 値が大きい場合は、GROUP BY の使用を検討してください。詳細については、COUNT(DISTINCT) をご覧ください。
  • クエリで UNIQUE を使用している場合は、代わりに GROUP BY を使用するか、サブセレクト内でウィンドウ関数を使用することを検討します。
  • クエリで LIMIT 句を使用して多くの行を実体化している場合は、別の列(ROW_NUMBER() など)でフィルタリングするか、LIMIT 句全体を削除して書き込みの並列化を可能にすることを検討してください。
  • クエリで深くネストされたビューと WITH 句を使用すると、複雑さが指数関数的に増加し、上限に達する可能性があります。
  • WITH 句ではなく一時テーブルを使用します。WITH 句の再計算が複数回必要になることがあります。その結果、クエリが複雑になり、処理速度が遅くなります。一時テーブルに中間結果を保存することで複雑さを軽減します。
  • UNION ALL クエリは使用しないでください。
  • クエリで MATCH_RECOGNIZE を使用している場合は、PARTITION BYを変更してパーティションのサイズを小さくするか、PARTITION BY 句が存在しない場合は追加します。

詳しくは、次のリソースをご覧ください。

読み込みジョブの場合:

Avro ファイルまたは Parquet ファイルを読み込む場合は、ファイルの行サイズを小さくします。読み込むファイル形式に固有のサイズ制限を確認します。

このエラーが ORC ファイルの読み込み時に発生した場合は、サポートにお問い合わせください。

Storage API の場合:

エラー文字列: Stream memory usage exceeded

Storage Read API の ReadRows 呼び出し時、メモリ使用量が多いストリームでは、このメッセージを伴う RESOURCE_EXHAUSTED エラーが発生することがあります。これは、ワイドテーブルや、複雑なスキーマを含むテーブルから読み取る際に発生することがあります。解決策としては、読み取る列の数を減らす(selected_fields パラメータを使用)か、テーブル スキーマを簡素化することで、結果の行サイズを減らします。

接続に関する問題のトラブルシューティング

以降のセクションでは、BigQuery を操作する際の接続に関する問題のトラブルシューティング方法について説明します。

Google DNS を許可リストに登録する

Google IP Dig ツールを使用して、BigQuery DNS エンドポイント bigquery.googleapis.com を単一の「A」レコード IP に解決します。この IP がファイアウォールの設定でブロックされていないことを確認してください。

通常は、Google DNS 名を許可リストに登録することをおすすめします。https://www.gstatic.com/ipranges/goog.json ファイルと https://www.gstatic.com/ipranges/cloud.json ファイルで共有される IP 範囲は頻繁に変更されるため、代わりに Google DNS 名を許可リストに登録することをおすすめします。許可リストに追加することをおすすめする一般的な DNS 名のリストは次のとおりです。

  • *.1e100.net
  • *.google.com
  • *.gstatic.com
  • *.googleapis.com
  • *.googleusercontent.com
  • *.appspot.com
  • *.gvt1.com

パケットをドロップしているプロキシまたはファイアウォールを特定する

クライアントと Google Front End(GFE)間のすべてのパケットホップを特定するには、クライアントマシンで traceroute コマンドを実行します。これにより、GFE に送信されるパケットをドロップしているサーバーがハイライト表示されます。traceroute コマンドの例を次に示します。

traceroute -T -p 443 bigquery.googleapis.com

問題が特定の IP アドレスに関連している場合は、特定の GFE IP アドレスのパケットホップを特定することもできます。

traceroute -T -p 443 142.250.178.138

Google 側にタイムアウトの問題がある場合は、リクエストが GFE まで到達します。

パケットが GFE に到達しない場合は、ネットワーク管理者にお問い合わせのうえ、この問題を解決してください。

PCAP ファイルを生成してファイアウォールまたはプロキシを分析する

パケット キャプチャ ファイル(PCAP)を生成してファイルを分析し、ファイアウォールまたはプロキシが Google IP へのパケットをフィルタリングしておらず、パケットが GFE に到達できるようにしていることを確認します。

tcpdump ツールで実行できるサンプル コマンドを次に示します。

tcpdump -s 0 -w debug.pcap -K -n host bigquery.googleapis.com

断続的な接続の問題の再試行を設定する

GFE ロードバランサがクライアント IP からの接続をドロップする場合があります。たとえば、DDoS トラフィック パターンが検出された場合や、ロードバランサ インスタンスがスケールダウンされ、エンドポイント IP がリサイクルされる可能性がある場合などです。GFE ロードバランサが接続を切断した場合、クライアントはタイムアウトしたリクエストをキャッチし、DNS エンドポイントへのリクエストを再試行する必要があります。IP アドレスが変更されている可能性があるため、リクエストが最終的に成功するまで同じ IP アドレスを使用しないでください。

再試行しても解決しない、Google 側でタイムアウトが常に発生する問題が見つかった場合は、Cloud カスタマーケアにお問い合わせください。その際は、tcpdump などのパケット キャプチャ ツールを実行して生成した新しい PCAP ファイルを添付してください。

次のステップ