在BigQuery中,从性能的角度来看,完成以下任务的最有效方法是什么?
目标:从table_a中选择与table_b中基于美国的行匹配的行。
我至少看到三种执行此任务的方法。
1)使用子查询进行过滤
SELECT * FROM table_a
JOIN (select * from table_b where country='US') table_b
ON table_a.userid = table_b.userid
2)使用连接子句进行过滤
SELECT * FROM table_a
JOIN table_b
ON table_a.userid = table_b.userid
AND table_b.country='US'
3)在末尾添加where子句
SELECT * FROM table_a
JOIN table_b
ON table_a.userid = table_b.userid
WHERE table_b.country='US'
答案 0 :(得分:3)
如果对这些查询使用standard SQL,则它们将以相同的方式执行,您可以通过在执行它们后查看query plan explanation来确认。具体来说,BigQuery应用了以下转换:
INNER JOIN
推送过滤器,因此将WHERE
放在联接之前的子查询中,类似于使其出现在联接之外。ON
子句中提取不相关的过滤器,因此将ON table_b.country='US'
与WHERE table_b.country='US'
一样对待。但是,如果您改用旧版SQL,则需要在连接之前将条件移到子查询中,因为使用旧版SQL时BigQuery不会通过连接“压低”过滤器。
答案 1 :(得分:0)
在您的情况下-我将与下面一起尽可能地缩小JOIN的数量。即使BigQuery Engine足够聪明,无论您使用哪个版本(在有问题的三个查询中),都可以为您自己进行此优化:
SELECT *
FROM table_a
JOIN (SELECT * FROM table_b WHERE country='US') table_b
ON table_a.userid = table_b.userid
但是如果您只需要来自table_a的行-我会选择类似
SELECT a.*
FROM table_a a
JOIN (SELECT DISTINCT userid FROM table_b WHERE country='US') table_b
ON a.userid = table_b.userid
答案 2 :(得分:0)
带有子查询的查询将是最慢的查询,然后是第3个查询,而最优化的查询是第2个查询,因为它仅使用join,而第3个查询同时使用join和WHERE子句。
您可以参考这些stackoverflow帖子,以加深了解。 联接和子查询之间的区别:Join vs. sub-query 连接和where子句之间的区别:Is a JOIN faster than a WHERE?
希望这会有所帮助!