我有 3 个表:
A
- id1
- data
B
- id1
- id2
- data
C
- id2
- data
表A 非常小,而表 B 和 C 可能很大。
表B 具有表 A 和 C 的联接键。因此,必须在第一个联接中存在。
- 根据我对Presto中的加入的理解,当基于成本时 未启用优化,联接执行的顺序为 加入的声明顺序。
- 此外,我们显然希望 在第一个连接操作中使用较小的表 A,因为这将 减小数据大小。
- 因此,这意味着第一个连接将位于表 A 和表 B 之间
- 但是,如果我想执行分布式联接, 则联接的构建侧(右侧(应较小 桌子。
- 因此,当我来到 AxB 和 C 结果之间的第二个连接时,连接的正确一侧不可避免地最终成为更大的表。
非常好奇人们通常如何处理普雷斯托的这种情况。如果分布式 Join 的构建端是左侧,那么我们总是将较小的表排序到左侧,这自然会飞起来。
按照定义的顺序执行联接并期望分布式联接的右侧表更小的想法似乎是矛盾的。
Presto 通常按声明的顺序执行连接(当基于成本的优化关闭时(,但如果可能,它会尽量避免交叉连接。如果对查询运行 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)