如何在 BigQuery 中使用连接修剪分区?
Posted
技术标签:
【中文标题】如何在 BigQuery 中使用连接修剪分区?【英文标题】:How to prune partitions with joins in BigQuery? 【发布时间】:2020-11-23 19:57:52 【问题描述】:我有两个表,其中包含两种不同类型的事件,这两个表都按事件的时间戳进行分区,我想创建一个它们之间的连接视图,它们具有相同的 id 和同一季度的事件。
CREATE TABLE `proj1.test.table1` ( event_timestamp TIMESTAMP, id INT64 ) 按日期划分(event_timestamp); CREATE TABLE `proj1.test.table2` ( event_timestamp TIMESTAMP, id INT64 ) 按日期划分(event_timestamp); 创建视图`proj1.test.view1`作为 选择 t1.event_timestamp,t1.id FROM `proj1.test.table1` t1 内连接`proj1.test.table2` t2 使用(ID) WHERE TIMESTAMP_TRUNC(t1.event_timestamp, Quarter) = TIMESTAMP_TRUNC(t2.event_timestamp, Quarter) ;问题是这个视图只修剪第一个表中的分区。
选择 * FROM test.view1 WHERE event_timestamp BETWEEN '2020-01-01' AND '2020-04-01'为了能够修剪两个表的分区,我必须使用文字表达式而不是计算值:
创建视图`proj1.test.view1`作为 选择 t1.event_timestamp,t1.id FROM `proj1.test.table1` t1 内连接`proj1.test.table2` t2 使用(ID) WHERE TIMESTAMP_TRUNC(t2.event_timestamp, 季度) = '2020-01-01'【问题讨论】:
【参考方案1】:你描述了the intended behaviour。我会尝试:
-
去掉视图并在
WHERE
子句中加倍过滤器。我经常这样做,因为它很简单:
SELECT t1.event_timestamp,t1.id
FROM test.table1 t1
INNER JOIN test.table2 t2
USING (id)
WHERE t1.event_timestamp BETWEEN '2020-01-01' AND '2020-04-01'
AND t2.event_timestamp BETWEEN '2020-01-01' AND '2020-04-01'
-
如果查询总是基于季度,添加另一个列和分区并加入它:
CREATE TABLE test.table1 ( event_timestamp TIMESTAMP, event_quarter DATE, id INT64 )
PARTITION BY event_quarter;
CREATE TABLE test.table2 ( event_timestamp TIMESTAMP, event_quarter DATE, id INT64 )
PARTITION BY event_quarter;
CREATE VIEW test.view1 AS
SELECT t1.*
FROM test.table1 t1
INNER JOIN test.table2 t2
USING (id, event_quarter);
SELECT *
FROM test.view1
WHERE event_quarter = '2020-01-01'
【讨论】:
谢谢史蒂文,虽然我想要一个更干净的选项,但这两个选项都有效。如果处理起来非常复杂,则使用真实案例(超过两个表)的第一个选项。从我的角度来看,第二个选项更好,但是您必须复制一列(具有典型问题)并且失去了使用时间戳使用较小分区(例如按天)的选项。以上是关于如何在 BigQuery 中使用连接修剪分区?的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript 中的 BigQuery 用户定义函数不会修剪分区