查询聚簇表

查询聚簇表

在 BigQuery 中创建聚簇表时,系统会根据表架构中一个或多个列的内容自动整理表数据。您指定的列用于共置相关数据。使用多个列对表进行聚簇时,指定列时的顺序很重要。指定列时的先后顺序决定了数据的排序顺序。

要在针对聚簇表运行查询时优化性能,请使用表达式对一个聚簇列或多个聚簇列(按指定聚簇列时的顺序)进行过滤。与仅对非聚簇列进行过滤的查询相比,对聚簇列进行过滤的查询的效果通常更好。

BigQuery 会根据聚簇列中的值对聚簇表中的数据排序,并将其整理为多个块。

当您提交包含对聚簇列进行过滤的查询时,BigQuery 会使用聚簇信息高效地确定某个块是否包含与查询相关的任何数据。这样一来,BigQuery 就可以仅扫描相关块(此过程称为块剪除)。

您可以通过以下方式查询聚簇表:

  • 使用 GCP Console 或传统版 BigQuery 网页界面
  • 使用命令行工具的 bq query 命令
  • 调用 jobs.insert API 方法并配置查询作业

目前,您只能对聚簇表使用标准 SQL

所需权限

要在数据集级层查询某个聚簇表,您需要拥有该表所属数据集的 READER 访问权限。

您可以利用包含 bigquery.tables.getData 权限的项目级层 IAM 角色,而不是使用数据集级层的权限。 读取所查询表中的数据需要 bigquery.tables.getData 权限。除了 bigquery.userbigquery.jobUserbigquery.metadataViewer 以外,其他所有预定义的项目级层 IAM 角色都具有 bigquery.tables.getData 权限。

要运行查询作业,您还必须获得 bigquery.jobs.create 权限。以下预定义的项目级层 IAM 角色包含 bigquery.jobs.create 权限:

如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅访问控制。如需详细了解数据集级层的角色,请参阅数据集的初始角色

最佳做法

要在查询聚簇表时获得最高性能,请使用以下最佳做法。

示例中使用的示例表

本页的示例中使用的示例表是一个使用 DDL 语句创建的聚簇表。这条 DDL 语句创建一个名为 ClusteredSalesData 的表。该表按以下列进行聚簇:首先按 customer_id,然后按 product_id,最后按 order_id

CREATE TABLE
  `mydataset.ClusteredSalesData`
PARTITION BY
  DATE(timestamp)
CLUSTER BY
  customer_id,
  product_id,
  order_id AS
SELECT
  *
FROM
  `mydataset.SalesData`

按照指定聚簇列时的顺序过滤聚簇列

指定过滤条件时,请使用按排序顺序过滤聚簇列的表达式。

以下查询会添加一个过滤表达式,该表达式先按 customer_id 进行过滤,然后按 product_id 进行过滤。此查询通过按排序顺序过滤聚簇列来优化性能。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  customer_id = 10000
  AND product_id LIKE 'gcp_analytics%'

以下查询不按排序顺序过滤聚簇列。因此,查询性能不是最佳的。此查询先按 product_id 进行过滤,然后按 order_id 进行过滤(跳过了 customer_id)。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  product_id LIKE 'gcp_analytics%'
  AND order_id = 20000

不要在复杂的过滤条件表达式中使用聚簇列

如果您在复杂过滤条件表达式中使用聚簇列,则查询性能不会优化,原因是无法应用块修剪。

例如,以下查询不会修剪块,因为聚簇列 customer_id 是用在过滤条件表达式中的函数中。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  CAST(customer_id AS STRING) = "10000"

要通过修剪块来优化查询性能,请使用类似于以下所示的简单过滤条件表达式。此示例对聚簇列 customer_id 应用了一个简单的过滤条件。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  customer_id = 10000

不要将聚簇列与其他列进行比较

如果过滤条件表达式将一个聚簇列与另一个列(可以是聚簇列,也可以是非聚簇列)进行比较,则查询性能不会优化,因为无法应用块修剪。

以下查询不会修剪块,因为过滤条件表达式将聚簇列 customer_id 与另一个列 (order_id) 进行比较。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  customer_id = order_id

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面