全球查询量

借助全球查询,您可以运行引用存储在多个区域中的数据的 SQL 查询。例如,您可以运行全球查询,将位于 us-central1 的表与位于 europe-central2 的表联接起来。本文档介绍了如何在项目中启用和运行全球查询。

准备工作

验证是否已为您的项目启用全球查询,并确保您拥有运行全球查询所需的权限。

启用全球查询

如需为项目或组织启用全球查询,请使用 ALTER PROJECT SET OPTIONS 语句或 ALTER ORGANIZATION SET OPTIONS 语句更改默认配置。

  • 如需在某个区域中运行全球查询,请在运行查询的项目中,将该区域的 enable_global_queries_execution 实参设置为 true。
  • 如需允许全球查询从某个区域复制数据,请在包含数据的项目中,将该区域的 enable_global_queries_data_access 实参设置为 true。
  • 每当您的查询访问远程表时,系统都会检查这些选项。
  • 全球查询可以在一个项目中运行,并从另一个项目中的其他区域提取数据。

示例:跨项目配置

以下示例展示了如何在一个项目中运行查询,以访问另一个项目中的表。

假设您有一个项目 query_project 在 us-central1 区域中运行作业,并且您想要运行一个查询来访问位于 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 Admin 角色是唯一包含此权限的预定义角色。如需在不授予 BigQuery Admin 角色的情况下授予运行全球查询的权限,请按照以下步骤操作:

  1. 创建自定义角色,例如“BigQuery 全球查询执行者”。
  2. 为此角色添加 bigquery.jobs.createGlobalQuery。
  3. 将此角色分配给所选用户或服务账号。

查询数据

如需运行全球查询,您只需像数据位于单个位置一样编写 SQL 查询。如果查询引用的数据存储在多个位置,BigQuery 会尝试执行全球查询。如果您未指定运行查询的位置,BigQuery 会根据所引用表的位置自动选择位置。如需了解详情,请参阅选择位置。查询引用的数据如果不在所选位置,则会被复制到该位置。

以下示例作为全球查询运行,该查询会合并存储在两个不同位置的两个不同数据集中的表:

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 语句),系统会选择创建或修改资源的位置作为执行位置。
  • 对于指定了目标表的查询,系统会选择目标表的位置作为执行位置。
  • 对于所有其他查询,系统会任意选择所引用数据集的其中一个位置作为执行位置。

了解全球查询

为了以高效且经济实惠的方式运行全球查询,请务必了解其执行背后的机制。

如需使用位于不同位置的数据,必须将其复制到一个位置。以下是 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 的所有数据从美国复制到欧盟。只需传输请求的列(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:父级全球查询作业的位置。系统会针对在远程区域中执行的子作业填充此字段。

查找全球查询的远程子作业

如需查找与父级全球查询关联的所有远程子作业,您可以使用 Log Analytics 或导出的日志接收器数据集查询审核日志:

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 不支持全球查询。
  • 使用区域端点时,不支持全球查询。
  • 沙盒模式不支持全球查询。
  • 由于在区域之间传输数据需要时间,全球查询的延迟时间比单区域查询更长。
  • 全球查询不会以原子方式执行。如果数据复制成功,但整个查询失败,您仍需为数据复制付费。
  • 单个全球查询在每个区域最多可以访问 10 个远程表。
  • 只有在配置为加密全球查询结果的 CMEK 密钥(在表、数据集或项目级层)是全球密钥时,系统才会使用客户管理的加密密钥 (CMEK) 加密在远程区域中创建的临时表(作为全球查询执行的一部分)。为确保始终使用 CMEK 保护远程临时表,请为在远程区域中运行全球查询的项目设置默认 KMS 密钥。
  • 不支持全局授权视图和授权例程(即一个位置的视图或例程有权访问另一个位置的数据集)。而应在数据所在区域创建已获授权的视图,并通过全球查询来查询这些视图。
  • 不支持对全球查询使用物化视图。
  • 您无法使用全球查询来查询 RANGE 类型列。
  • 您无法使用全球查询来查询伪列,例如 _PARTITIONTIME。
  • 您无法使用全球查询来查询使用灵活列名称的列。
  • 如果全球查询引用 STRUCT 列,则系统不会对任何远程子查询应用下推。为了优化性能,请考虑在远程区域中创建一个视图,用于过滤 STRUCT 列,并仅以单独的列形式返回必要的字段。
  • 查询的执行详情和执行图不会显示从远程位置处理和传输的字节数。此信息会显示在您可以在作业历史记录中找到的复制作业中。由全球查询创建的复制作业的作业 ID 会以查询作业的作业 ID 作为前缀。
  • 只有在数据洞察中封装在视图中并配置为使用查看者凭证时,才支持全球查询。