BigQuery:如何在分区表上运行分析函数查询

时间:2020-05-06 08:05:30

标签: google-bigquery

我有一个表,其中包含相同数据的多个版本。每个版本都可以通过时间戳字段来标识。

这是我想到的使用窗口函数仅获取最新版本数据的查询:

WITH tbl AS (
  SELECT
    *,
    first_value(`timestamp`) OVER (PARTITION BY concatenate ORDER BY `timestamp` DESC) AS latest
  FROM
    dataset.table as tbl
)

SELECT
  *  
FROM tbl
WHERE
  `timestamp` = latest;

串联是代表我的行的唯一性的字段的组合。

这很有效,但是,为了对此进行优化,我创建了一个分区表,以减少由于数据的许多版本而在查询中处理的数据量:

CREATE TABLE
  `dataset.partitioned_table`
PARTITION BY
  DATE(`timestamp`)
  CLUSTER BY concatenate AS
SELECT * FROM `dataset.table`;

但是,当我对新的分区数据运行查询时,BigQuery会像处理未分区的数据一样处理确切的数据量,因为它应该处理大约三分之一的数据(我正在测试3种版本的数据)。

我的感觉是窗口函数正在处理整个数据,使用分区表时可能会有更好的方法来完成此操作,但是,我仍然找不到执行该操作的方法。

还尝试按假日期创建表分区,但按时间戳记和连接字段进行聚类,但结果相同。

1 个答案:

答案 0 :(得分:2)

由于查询的编写方式,每次查询都会读取整个表。

检查CTE(WITH子句),它不受任何WHERE子句的限制,以减少读取的数据量。

如果您只想读取表的最新分区,则必须执行以下操作:

WITH tbl AS (
  SELECT
    *,
    first_value(`timestamp`) OVER (PARTITION BY concatenate ORDER BY `timestamp` DESC) AS latest
  FROM
    dataset.table as tbl

  #### this is the super important bit to reduce your reads ####
  WHERE DATE(timestamp) >= DATE('whatever_you_think_your_last_few_partitions_should_be')

)

SELECT
  *  
FROM tbl
WHERE
  `timestamp` = latest;

基本上,您需要在查询的早期使用WHERE进行过滤,以减少处理的数据量。

请记住,我添加了whatever_you_think_your_last_few_partitions_should_be,因为这实际上取决于您是否要扫描最后X个分区中的重复项,或者要扫描1周的日期范围,或者实际上是最后一天。取决于您的解决方案。