グローバル クエリ

グローバル クエリを使用すると、複数のリージョンに保存されているデータを参照する SQL クエリを実行できます。異なる地理的位置にあるテーブルを結合すると、データセットを手動で移動または統合することなく、分散データを分析できます。

始める前に

プロジェクトでグローバル クエリが有効になっていることを確認し、グローバル クエリを実行するために必要な権限があることを確認します。

グローバル クエリを有効にする

プロジェクトまたは組織でグローバル クエリを有効にするには、ALTER PROJECT SET OPTIONS ステートメントまたは ALTER ORGANIZATION SET OPTIONS ステートメントを使用して、デフォルト構成を変更します。

  • リージョンでグローバル クエリを実行するには、クエリを実行するプロジェクトのそのリージョンで enable_global_queries_execution 引数を true に設定します。
  • グローバル クエリでリージョンからデータをコピーできるようにするには、データを含むプロジェクトのそのリージョンで enable_global_queries_data_access 引数を true に設定します。
  • クエリがリモート テーブルにアクセスするたびに、これらのオプションがチェックされます。
  • グローバル クエリは 1 つのプロジェクトで実行し、別のプロジェクトから他のリージョンのデータを取得できます。

例: プロジェクト間の構成

次の例は、あるプロジェクトでクエリを実行して、別のプロジェクトのテーブルにアクセスする方法を示しています。

us-central1 リージョンでジョブを実行しているプロジェクト query_project があり、europe-west1 リージョンにあるテーブル data_project.dataset.my_table にアクセスするクエリを実行するとします。

SET @@location='us-central1';
SELECT
  *
FROM
  `query_project.dataset.my_table`
  JOIN `data_project.dataset.my_other_table` USING id;

このグローバル クエリを正常に実行するには、次の構成が必要です。

  1. グローバル クエリを実行するリージョン(us-central1)のプロジェクト(query_project)で、グローバル クエリの実行を有効にする必要があります。

    ALTER PROJECT `query_project`
    SET OPTIONS (
    `region-us-central1.enable_global_queries_execution` = TRUE
    )
  2. データを含むプロジェクト(data_project)から、そのリージョン(europe-west1)のグローバル クエリによるデータのコピーを有効にする必要があります。

    ALTER PROJECT `data_project`
    SET OPTIONS (
    `region-europe-west1.enable_global_queries_data_access` = TRUE
    )

リモートテーブルを含むビューを作成して使用する場合も、同じ原則が適用されます。クエリを実行するプロジェクトで enable_global_queries_execution を有効にする必要があります。

これらの ALTER PROJECT オペレーションは、異なるプロジェクトとリージョンを参照するため、個別に実行する必要があります。変更が有効になるまで数分かかることがあります。

必要な権限

グローバル クエリを実行するには、bigquery.jobs.createGlobalQuery 権限が必要です。この権限を含む事前定義ロールは、BigQuery 管理者ロールのみです。BigQuery 管理者ロールを付与せずにグローバル クエリを実行する権限を付与する手順は次のとおりです。

  1. カスタムロール(「BigQuery グローバル クエリ実行者」など)を作成します。
  2. このロールに bigquery.jobs.createGlobalQuery を追加します。
  3. このロールを選択したユーザーまたはサービス アカウントに割り当てます。

データのクエリ

グローバル クエリを実行するには、データが 1 つのロケーションにある場合と同様に SQL クエリを作成します。クエリで参照されるデータが複数のロケーションに保存されている場合、BigQuery はグローバル クエリの実行を試みます。クエリを実行するロケーションを指定しない場合、BigQuery は参照されるテーブルのロケーションに基づいてロケーションを自動的に選択します。詳細については、ロケーションを選択するをご覧ください。選択したロケーションに存在しないクエリによって参照されるデータは、そのロケーションにコピーされます。

次の例は、2 つの異なるロケーションに保存されている 2 つの異なるデータセットのテーブルを結合するグローバル クエリとして実行されます。

SELECT id, tr_date, product_id, price FROM us_dataset.transactions
UNION ALL
SELECT id, tr_date, product_id, price FROM europe_dataset.transactions

ロケーションを選択してください

グローバル クエリを実行する場所を構成するには、ロケーションを指定します。グローバル クエリの実行場所を決定する際は、次の点を考慮してください。

  • データ所在地: グローバル クエリは、あるロケーションから別のロケーションにデータを一時的にコピーします。組織にデータ所在地に関する要件があり、データを特定のロケーションから移動させたくない場合は、クエリのロケーションをそのロケーションに設定します。

  • 転送費用とパフォーマンス: ロケーション間で転送されるデータ量を最小限に抑え、クエリの費用を削減するには、クエリ対象のデータの大部分が保存されているリージョンでクエリを実行します。

    たとえば、オンライン ショップを運営していて、商品のリストをロケーション us-central1 に保存し、トランザクションを us-south1 リージョンに保存しているとします。カタログ内の商品よりもトランザクションが多い場合は、us-south1 リージョンでクエリを実行する必要があります。

  • 予約とコンピューティング容量: クエリのロケーションを指定して、クエリを処理するリージョン予約またはスロットを制御します。

ロケーションを手動で指定しない場合、BigQuery は次の条件に基づいて実行ロケーションを自動的に決定します。

  • データ操作言語(DML)クエリ(INSERT、UPDATE、DELETE ステートメント)の場合、ターゲット テーブルのロケーションが実行ロケーションとして選択されます。
  • データ定義言語(DDL)クエリ(CREATE TABLE AS SELECT ステートメントなど)の場合、リソースが作成または変更されるロケーションが実行ロケーションとして選択されます。
  • 宛先テーブルが指定されているクエリの場合、宛先テーブルのロケーションが実行ロケーションとして選択されます。
  • 他のすべてのクエリでは、参照されるデータセットのロケーションの 1 つとして実行ロケーションが任意に選択されます。

グローバル クエリについて

グローバル クエリを効率的かつ費用対効果の高い方法で実行するには、実行の背後にあるメカニズムを理解することが重要です。

異なるロケーションに存在するデータを使用するには、1 つのロケーションに複製する必要があります。以下は、BigQuery によって実行されるグローバル クエリ ワークフローの抽象化です。

  1. ユーザーの宣言または自動的に、クエリを実行する場所を決定します。このロケーションはプライマリ ロケーションと呼ばれ、クエリで参照される他のすべてのロケーションはリモートです。
  2. 各リモート リージョンでサブクエリを実行して、プライマリ リージョンでクエリを完了するために必要なデータを収集する。
  3. このデータをリモート ロケーションからプライマリ ロケーションにコピーします。
  4. データをプライマリ ロケーションの一時テーブルに 24 時間保存する。10 GiB 未満のサブクエリ結果の場合、リージョン間でデータが転送されないように、データがキャッシュに保存されて再利用されることがあります。
  5. プライマリ ロケーションで収集されたすべてのデータに対して最終クエリを実行する。
  6. クエリ結果を返します。

BigQuery は、リージョン間で転送されるデータ量を最小限に抑えようとします。たとえば次のようになります。

SET @@location = 'EU';
SELECT
  t1.col1, t2.col2
FROM
  eu_dataset.table1 t1
  JOIN us_dataset.table2 t2 using col3
WHERE
  t2.col4 = 'ABC'

BigQuery は、テーブル t2 のすべてを米国から EU に複製する必要はありません。リクエストされた列(col2 と col3)と、WHERE 条件(t2.col4 = 'ABC')に一致する行のみを転送するだけで十分です。ただし、これらのメカニズム(プッシュダウン)はクエリ構造に依存し、転送されるデータの量が大きくなることがあります。グローバル クエリをデータの小さなサブセットでテストし、必要な場合にのみデータが転送されることを確認することをおすすめします。

オブザーバビリティ

グローバル クエリをモニタリングし、リージョン間での実行を検査するには、次の方法を使用します。

ジョブ履歴

リモート リージョンに送信されたクエリテキストを確認するには、ジョブ履歴を確認します。リモートジョブのジョブ ID は、元のクエリと同じですが、_xregion 接尾辞が追加されています。

Jobs REST API

jobs.get メソッドを呼び出すと、返される Job リソースの JobStatistics オブジェクトに次のフィールドが含まれます。

  • statistics.globalQueryRemoteRegions: グローバル クエリがデータにアクセスするリモート リージョンを表す文字列の配列。このフィールドは、プライマリ実行リージョンの親グローバル クエリジョブに対してのみ入力されます。子グローバル クエリジョブとシングルリージョン クエリの場合は空です。
  • statistics.parentGlobalQueryJob: 親グローバル クエリジョブを識別する JobReference オブジェクト(projectId、jobId、location)。このフィールドは、グローバル クエリに代わってリモート リージョンで実行される子グローバル クエリジョブ(リモート サブクエリとクロスリージョン コピージョブ)にのみ入力されます。親グローバル クエリジョブと単一リージョン クエリの場合は設定されません。

監査ログ

Cloud Audit Logs では、BigQueryAuditMetadata オブジェクトの JobStats オブジェクトに次のフィールドが含まれています。

  • jobStats.globalQueryRemoteRegions: クエリによってアクセスされたリモート リージョンを表す文字列の配列。このフィールドは、プライマリ実行リージョンの親グローバル クエリジョブにのみ入力されます。
  • jobStats.parentGlobalQueryJobId: 親グローバル クエリジョブのジョブ ID。このフィールドは、リモート リージョンで実行された子ジョブに入力されます。
  • jobStats.parentGlobalQueryJobLocation: 親グローバル クエリジョブのロケーション。このフィールドは、リモート リージョンで実行された子ジョブに入力されます。

グローバル クエリのリモート子ジョブを検索する

親グローバル クエリに関連付けられているすべてのリモート子ジョブを検索するには、ログ分析またはエクスポートされたログシンク データセットを使用して監査ログをクエリします。

SELECT
  timestamp,
  proto_payload.audit_log.resource_name AS resource_name,
  JSON_VALUE(proto_payload.audit_log.metadata.jobChange.job.jobConfig.queryConfig.query) AS query
FROM
  `PROJECT_ID.LOG_DATASET._AllLogs`
WHERE
  JSON_VALUE(proto_payload.audit_log.metadata.jobChange.job.jobStats.parentGlobalQueryJobId) = 'PARENT_JOB_ID';

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

  • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
  • LOG_DATASET: オブザーバビリティ分析にリンクされた BigQuery データセット、またはログシンクの宛先データセット。
  • PARENT_JOB_ID: 親グローバル クエリジョブのジョブ ID。

INFORMATION_SCHEMA ビュー

INFORMATION_SCHEMA.JOBS ビューと INFORMATION_SCHEMA.JOBS_TIMELINE ビューに対してクエリを実行して、グローバル クエリのメタデータを検査できます。global_query_info 列には次のフィールドが含まれています。

  • parent_job_id: プライマリ リージョンの親グローバル クエリジョブの ID。このフィールドは、リモート リージョンで実行された子サブクエリとコピージョブに入力されます。
  • parent_job_location: 親グローバル クエリジョブのロケーション。
  • remote_regions: クエリで参照されるリモート リージョンの配列。このフィールドは、プライマリ リージョンの親グローバル クエリジョブに入力されます。

プライマリ リージョンでグローバル クエリを特定する

プライマリ リージョンで実行されたすべてのグローバル クエリを検索し、参照されたリモート リージョンを確認するには、プライマリ リージョンの INFORMATION_SCHEMA.JOBS ビューに対してクエリを実行します。

SELECT
  job_id,
  creation_time,
  query,
  total_bytes_billed,
  global_query_info.remote_regions
FROM
  `region-REGION`.INFORMATION_SCHEMA.JOBS
WHERE
  ARRAY_LENGTH(global_query_info.remote_regions) > 0;

REGION は、グローバル クエリが実行されたリージョン(us-central1 など)に置き換えます。

グローバル クエリのリモート子ジョブを検索する

親グローバル クエリに関連付けられているすべてのリモート子ジョブを検索するには、リモート リージョンの INFORMATION_SCHEMA.JOBS ビューをクエリします。

SELECT
  job_id,
  project_id,
  job_type,
  statement_type,
  total_bytes_billed,
  total_slot_ms
FROM
  `region-REMOTE_REGION`.INFORMATION_SCHEMA.JOBS
WHERE
  global_query_info.parent_job_id = 'PARENT_JOB_ID';

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

  • REMOTE_REGION: 子サブクエリまたはコピージョブが実行されたリモート リージョン(europe-west1 など)。
  • PARENT_JOB_ID: 親グローバル クエリジョブのジョブ ID。

グローバル クエリをオフにする

プロジェクトまたは組織のグローバル クエリを無効にするには、ALTER PROJECT SET OPTIONS statement または ALTER ORGANIZATION SET OPTIONS statement を使用してデフォルト構成を変更します。

  • リージョンでグローバル クエリをオフにするには、そのリージョンで enable_global_queries_execution 引数を false または NULL に設定します。
  • グローバル クエリがリージョンからデータをコピーできないようにするには、そのリージョンで enable_global_queries_data_access 引数を false または NULL に設定します。

次の例は、プロジェクト レベルでグローバル クエリを無効にする方法を示しています。

ALTER PROJECT PROJECT_ID
SET OPTIONS (
  `region-REGION.enable_global_queries_execution` = false,
  `region-REGION.enable_global_queries_data_access` = false
);

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

  • PROJECT_ID: 変更するプロジェクトの名前
  • REGION: グローバル クエリを無効にするリージョンの名前

変更が有効になるまで数分かかることがあります。

料金

グローバル クエリの費用は、次のコンポーネントで構成されます。

  • リモート ロケーションの各サブクエリのコンピューティング費用。これらのロケーションの料金モデルに基づきます。
  • 最終クエリが実行されるリージョンでのコンピューティング費用(そのリージョンの料金モデルに基づく)
  • 異なるロケーション間でデータをコピーする費用(データ レプリケーションの料金に基づく)
  • リモート リージョンからプライマリ リージョンにコピーされたデータを保存する費用(24 時間)。ストレージ料金をご覧ください。

割り当て

グローバル クエリの割り当てについては、クエリジョブをご覧ください。

制限事項

  • グローバル クエリは Assured Workloads ではサポートされていません。
  • リージョン エンドポイントを使用する場合、グローバル クエリはサポートされません。
  • グローバル クエリはサンドボックス モードではサポートされていません。
  • グローバル クエリは、リージョン間でデータを転送するのに時間がかかるため、単一リージョン クエリよりもレイテンシが高くなります。
  • グローバル クエリはアトミックに実行されません。データ レプリケーションが成功しても、クエリ全体が失敗した場合は、データ レプリケーションに対して課金されます。
  • 1 つのグローバル クエリで、リージョンごとに最大 10 個のリモートテーブルにアクセスできます。
  • グローバル クエリの実行の一環としてリモート リージョンに作成された一時テーブルは、グローバル クエリの結果を暗号化するように構成された CMEK 鍵(テーブル、データセット、プロジェクト レベルのいずれか)がグローバルである場合にのみ、顧客管理の暗号鍵(CMEK)を使用して暗号化されます。リモートの一時テーブルが常に CMEK を使用して保護されるようにするには、リモート リージョンでグローバル クエリを実行するプロジェクトにデフォルトの KMS 鍵を設定します。
  • グローバル承認済みビューと承認済みルーティンはサポートされていません(あるロケーションのビューまたはルーティンが別のロケーションのデータセットにアクセスすることを承認されている場合)。代わりに、データが配置されているリージョンに承認済みビューを作成し、グローバル クエリを介して承認済みビューにクエリを実行します。
  • グローバル クエリに対するマテリアライズド ビューはサポートされていません。
  • グローバル クエリで RANGE 型指定された列をクエリすることはできません。
  • グローバル クエリを使用して、_PARTITIONTIME などの疑似列をクエリすることはできません。
  • グローバル クエリで柔軟な列名を使用して列をクエリすることはできません。
  • グローバル クエリが STRUCT 列を参照している場合、リモート サブクエリにプッシュダウンは適用されません。パフォーマンスを最適化するには、リモート リージョンでビューを作成し、STRUCT 列をフィルタして、必要なフィールドのみを個々の列として返すようにすることをご検討ください。
  • クエリの実行の詳細と実行グラフには、リモート ロケーションから処理および転送されたバイト数が表示されません。この情報は、ジョブ履歴で確認できるコピージョブに表示されます。グローバル クエリによって作成されたコピージョブのジョブ ID には、クエリジョブのジョブ ID が接頭辞として付いています。
  • グローバル クエリは、ビューにラップされ、閲覧者の認証情報を使用するように構成されている場合にのみ、データポータルでサポートされます。