Presto 多表连接和广播连接分布

Posted

技术标签:

【中文标题】Presto 多表连接和广播连接分布【英文标题】:Presto Multi table Join with Broadcast Join Distribution 【发布时间】:2020-10-08 13:57:26 【问题描述】:

我有 3 张桌子:

A
 - id1
 - data
B 
 - id1
 - id2
 - data
C
 - id2
 - data

表 A 非常小,而表 B 和 C 可能很大。

表 B 具有表 A 和 C 的连接键。因此,必须存在于第一个连接中。

根据我对 Presto 中加入的了解,基于成本 未启用优化,加入执行的顺序是 连接的声明顺序。 此外,我们显然希望 在第一个 Join 操作中有较小的表 A,因为这将 减少数据大小。 因此,这意味着第一个联接将在表 A 和 B 之间 但是,如果我想执行分布式连接, 那么 Join 的构建侧(右侧)应该更小 表。 因此,当我在 AxB 和 C 的结果之间进行第二次联接时,不可避免地,联接的右侧最终会成为更大的表。

很好奇人们通常如何在 Presto 中处理这种情况。如果分布式连接的构建端是左侧,那么我们总是将较小的表排序到左侧就很自然了。

按照定义的顺序执行连接和期望分布式连接的右侧表更小的想法似乎是矛盾的。

【问题讨论】:

【参考方案1】:

Presto 通常按照声明的顺序执行连接(当基于成本的优化关闭时),但如果可能,它会尝试avoid cross joins。如果您对查询运行 EXPLAIN,您应该能够看到查询的实际连接顺序。

对于上面的示例,您可以通过强制使用括号进行右关联连接来手动避免交叉连接,类似于算术的工作原理(例如,a - (b - c)):

WITH 
   a(x) AS (VALUES(1)), 
   b(x,y) AS (VALUES (1,'a')), 
   c(y) AS (VALUES 'a')
SELECT * 
FROM c JOIN (b JOIN a USING (x)) USING (y)

【讨论】:

以上是关于Presto 多表连接和广播连接分布的主要内容,如果未能解决你的问题,请参考以下文章

Oracle Inner Join子句(多表连接)

Mysql-多表连接的操作和用法

mysql 数据操作 多表查询 目录

SQL多表连接

TypeORM 无关联关系的mysql多表连接查询

MySQL多表连接查询