グローバル クエリ
グローバル クエリを使用すると、複数のリージョンに保存されているデータを参照する 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;
このグローバル クエリを正常に実行するには、次の構成が必要です。
グローバル クエリを実行するリージョン(
us-central1)のプロジェクト(query_project)で、グローバル クエリの実行を有効にする必要があります。ALTER PROJECT `
query_project` SET OPTIONS ( `region-us-central1.enable_global_queries_execution` = TRUE )データを含むプロジェクト(
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 管理者ロールを付与せずにグローバル クエリを実行する権限を付与する手順は次のとおりです。
- カスタムロール(「BigQuery グローバル クエリ実行者」など)を作成します。
- このロールに
bigquery.jobs.createGlobalQueryを追加します。 - このロールを選択したユーザーまたはサービス アカウントに割り当てます。
データのクエリ
グローバル クエリを実行するには、データが 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 によって実行されるグローバル クエリ ワークフローの抽象化です。
- ユーザーの宣言または自動的に、クエリを実行する場所を決定します。このロケーションはプライマリ ロケーションと呼ばれ、クエリで参照される他のすべてのロケーションはリモートです。
- 各リモート リージョンでサブクエリを実行して、プライマリ リージョンでクエリを完了するために必要なデータを収集する。
- このデータをリモート ロケーションからプライマリ ロケーションにコピーします。
- データをプライマリ ロケーションの一時テーブルに 24 時間保存する。10 GiB 未満のサブクエリ結果の場合、リージョン間でデータが転送されないように、データがキャッシュに保存されて再利用されることがあります。
- プライマリ ロケーションで収集されたすべてのデータに対して最終クエリを実行する。
- クエリ結果を返します。
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 PROJECTPROJECT_IDSET 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 が接頭辞として付いています。
- グローバル クエリは、ビューにラップされ、閲覧者の認証情報を使用するように構成されている場合にのみ、データポータルでサポートされます。