我有一个表,其中包含相同数据的多个版本。每个版本都可以通过时间戳字段来标识。
这是我想到的使用窗口函数仅获取最新版本数据的查询:
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种版本的数据)。
我的感觉是窗口函数正在处理整个数据,使用分区表时可能会有更好的方法来完成此操作,但是,我仍然找不到执行该操作的方法。
还尝试按假日期创建表分区,但按时间戳记和连接字段进行聚类,但结果相同。
答案 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周的日期范围,或者实际上是最后一天。取决于您的解决方案。