全球查询

借助全球查询,您可以运行 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_projectus-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 global queries executor”。
  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

自动位置选择

在以下情况下,系统会自动确定必须在其中执行查询的位置,并且无法更改:

  • 数据修改语言查询(INSERTUPDATEDELETE 语句)始终在目标表的位置执行。
  • 数据定义语言查询(例如 CREATE TABLE AS SELECT 语句)始终在创建或修改资源的位置执行。
  • 指定了目标表 的查询始终在目标表所在的位置执行。

选择位置

一般来说,您可以决定在全球查询的执行位置。如需做出此决定,请考虑以下事项:

  • 全球查询会暂时将数据从一个位置复制到另一个位置。如果您的组织对数据驻留有任何要求,并且您不希望位置 A 中的数据离开位置 A,请将查询位置设置为 A。

  • 如需最大限度地减少在位置之间传输的数据量并降低查询费用,请在存储了大部分查询数据的区域中运行查询。

假设您有一家在线商店,并且在位置 us-central1保留了产品列表,但在us-south1区域中保留了交易记录。如果交易记录的数量多于产品目录中的产品数量 ,则应在 us-south1 区域中运行查询。

了解全球查询

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

如需使用位于不同位置的数据,必须将这些数据复制到一个位置。以下是 BigQuery 执行的全球查询工作流的抽象表示:

  1. 确定必须在其中执行查询的位置,可以根据用户的声明确定,也可以自动确定。此位置称为 主要 位置,查询引用的所有其他位置都是 远程 位置。
  2. 在每个远程区域中运行子查询,以收集在主要区域中完成查询所需的数据。
  3. 将这些数据从远程位置复制到主要位置。
  4. 将数据保存在主要位置的临时表中,保留 24 小时。
  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 的所有数据从美国复制到欧盟。 只需传输请求的列(col2col3)以及与 WHERE 条件 (t2.col4 = 'ABC') 匹配的行即可。不过,这些机制(称为 下推)取决于查询结构,有时传输的数据量可能会很大。我们建议您对少量数据测试全球查询,并确认仅在需要时才传输数据。

可观测性

如需监控全球查询并检查其在各个区域中的执行情况,您可以使用以下方法:

作业历史记录

如需查看发送到远程区域的查询文本,请查看作业历史记录。远程作业的作业 ID 与原始查询的作业 ID 相同,但会添加 _xregion 后缀。

Jobs REST API

当您调用 jobs.get 方法时,返回的 Job 资源会在 JobStatistics 对象中包含以下字段:

  • statistics.global_query_remote_regions:一个字符串数组,表示全球查询从中访问数据的远程区域。此字段仅针对主要执行区域中的父级全球查询作业进行填充。对于子级全球查询作业和单区域查询,此字段为空。
  • statistics.parent_global_query_job:一个 JobReference 对象(projectIdjobIdlocation),用于标识父级全球查询作业。此字段仅针对代表全球查询在远程区域中执行的子级全球查询作业(远程子查询和跨区域复制作业)进行填充。对于父级全球查询作业和单区域查询,此字段处于未设置状态。

审核日志

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。

关闭全球查询

如需为项目或组织停用全球查询,请使用 ALTER PROJECT SET OPTIONS statementALTER ORGANIZATION SET OPTIONS statement 更改默认配置

  • 如需在某个区域中关闭全球查询,请在该区域中将 enable_global_queries_execution 实参设置为 falseNULL
  • 如需禁止全球查询从某个区域复制数据,请在该区域中将 enable_global_queries_data_access 实参设置为 falseNULL

以下示例展示了如何在项目级层停用全球查询:

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 小时)的费用,具体取决于存储价格

配额

如需了解全球查询的配额,请参阅查询作业

限制

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