假设我在BigQuery中有两个表,l
和r
。
两者具有相同的结构:
ts
TIMESTAMP
a
INTEGER
b
INTEGER
此外,两者都在ts
字段上按时间划分。主要区别在于r
具有一些重复的行,而l
仅具有唯一的(a
,b
,ts
)元组。
显然,实际用例更加复杂,我尽可能地简化了数据。
以下查询处理1.2 GB
数据。
select l.ts, l.a, l.b
from l
join r using(ts, a, b)
如果我仅保留一周的数据,则消耗将降低至48.5 MB
。
select l.ts, l.a, l.b
from l
join r using(ts, a, b)
where date(l.ts) between "2020-03-16" and "2020-03-22"
但是,如果我切换到左联接,则消耗将上升到673.5 MB
。
select l.ts, l.a, l.b
from l
left join r using(ts, a, b)
where date(l.ts) between "2020-03-16" and "2020-03-22"
表l
和r
分别包含530.4 MB
和652.2 MB
。在日期范围上进行过滤后,这些数字将分别降为21.3 MB
和27.1 MB
。
切换到左联接时,673.5 MB
的消耗等于21.3 MB
+ 652.2 MB
(l
的分区扫描+ r
的完整扫描)。
我不明白为什么在使用左联接时我们无法减少表r
中扫描的数据量。这是预期的吗?在这种情况下,为什么?
在实际用例中,我必须使用左联接。一种解决方法是使用下面的查询,该查询按预期消耗48.5 MB
。
select l.ts, l.a, l.b
from (select * from l where ts between "2020-03-16" and "2020-03-22") l
left join (select * from r where ts between "2020-03-16" and "2020-03-22") using(ts, a, b) r
但是对于我的用例(与Tableau一起使用),它远非理想。