在BigQuery SQL中,通常最有效的联接和过滤第二张表的方法是什么?

时间:2018-09-20 16:04:40

标签: google-bigquery

在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'

3 个答案:

答案 0 :(得分:3)

如果对这些查询使用standard SQL,则它们将以相同的方式执行,您可以通过在执行它们后查看query plan explanation来确认。具体来说,BigQuery应用了以下转换:

  • BigQuery通过INNER JOIN推送过滤器,因此将WHERE放在联接之前的子查询中,类似于使其出现在联接之外。
  • BigQuery从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?

希望这会有所帮助!