全球查询量
借助全球查询,您可以运行引用存储在多个区域中的数据的 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;
为确保此全球查询能够成功执行,需要进行以下配置:
您需要在运行全球查询 (
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 Admin 角色是唯一包含此权限的预定义角色。如需在不授予 BigQuery Admin 角色的情况下授予运行全球查询的权限,请按照以下步骤操作:
- 创建自定义角色,例如“BigQuery 全球查询执行者”。
- 为此角色添加
bigquery.jobs.createGlobalQuery。 - 将此角色分配给所选用户或服务账号。
查询数据
如需运行全球查询,您只需像数据位于单个位置一样编写 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 执行的全球查询工作流的抽象表示:
- 确定必须在何处执行查询,可以根据用户声明或自动确定。此位置称为主要位置,查询引用的所有其他位置都是远程位置。
- 在每个远程区域中运行子查询,以收集在主要区域中完成查询所需的数据。
- 将这些数据从远程位置复制到主要位置。
- 将数据保存在主要位置的临时表中,保留 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 的所有数据从美国复制到欧盟。只需传输请求的列(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 PROJECTPROJECT_IDSET 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 作为前缀。
- 只有在数据洞察中封装在视图中并配置为使用查看者凭证时,才支持全球查询。