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

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

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

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

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

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

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

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

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

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

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

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 raw access permissions 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 句を含むクエリなどです。

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

ジョブが見つからない

エラー文字列: Job not found

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

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

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

エラー文字列: 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 エラー メッセージのガイダンスに従ってください。

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

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

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

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

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

ユーザーに権限がない

エラー文字列:

  • 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.

このエラーは、クエリを実行するプロジェクトに bigquery.jobs.create 権限がない状態でクエリを実行した場合に発生します。データを含むプロジェクトに対する権限に関係なく、このエラーが発生します。また、クエリで参照するすべてのテーブルとビューに対する bigquery.tables.getData 権限も必要です。

このエラーは、asia-south1 などのクエリされたリージョンに、テーブルが存在しない場合にも発生することがあります。ビューにクエリを実行するには、基になるすべてのテーブルとビューに対するこの権限も必要です。必要な権限の詳細については、クエリを実行するをご覧ください。

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

  • サービス アカウント: サービス アカウントには、実行するプロジェクトに対する bigquery.jobs.create 権限が必要です。

  • カスタムロール: IAM カスタムロールには、関連するロールに bigquery.jobs.create 権限が明示的に含まれている必要があります。

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

テーブルへのアクセス権を付与する

テーブルへのアクセス権をプリンシパルに付与する手順は次のとおりです。

  1. [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. [エクスプローラ] で、アクセスするテーブルを参照し、 [アクションを表示]、[共有] の順に選択して、[権限を管理] をクリックします。

  3. [プリンシパルを追加] で、追加するユーザー、グループ、ドメイン、またはサービス アカウントの名前を入力します。

  4. [ロールを割り当てる] で、bigquery.jobs.create 権限を選択します。クエリを実行するプロジェクトで roles/bigquery.jobUser ロールを付与すると、必要な権限が付与されます。

  5. [保存] をクリックします。

リソース超過の問題

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

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

エラー文字列: Query exceeded resource limits

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

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

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

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

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

エラー文字列: 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 句で置き換えないでください。この句の再計算が複数回必要になることがあります。その場合、クエリが複雑になり、処理速度が遅くなる可能性があります。一時テーブルに中間結果を保存することで複雑さが軽減されます。
  • UNION ALL クエリは使用しないでください。

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

読み込みジョブの場合:

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

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

Storage API の場合:

エラー文字列: Stream memory usage exceeded

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

次のステップ