在单个配置单元查询中使用三个或更多连接

Using three or more joins within a single hive query

下午好,请告诉我这两种情况的输出是否相同?如果您需要在单个配置单元查询中使用三个或更多不同的联接,有哪些替代方案。

from a
  join b on a.key=b.key
  join c on a.key=c.key
  left join u on a.key=u.key


_______
from a
  join b on a.key=b.key
  left join u on a.key=u.key
  join c on a.key=c.key

结果应该相同,但性能可能不同。联接可以复制或减少行数。

如果连接键不是唯一的,所有类型的连接都可以复制行(左半连接除外,它可能会也可能不会减少行数)。这是正常行为,可以有意为之。复制之后的每个后续连接都将处理更多行,这肯定会影响性能。

检查加入密钥在您要加入的 table 中是唯一的,以消除重复。

如果键不匹配,内连接也可以减少行数(类似于左半连接)。后续连接将处理更少的行,这将提高性能。同时 inner join 可以复制行(见上文)。

如果您想提高性能,减少数据集的连接应该在其他连接之前完成。 如果可能,在 join ON 条件下进行过滤,因为它比 WHERE 更有效 子句,在所有连接之后应用。 连接复制行(有意)应该最后执行。

通常情况下,CBO 会根据统计数据来决定应该首先完成哪些联接。或者,您可以显式地将连接分组到子查询中,以确保首先执行减少数据集的连接。例如像这样:

  from
  (--Do inner joins first to reduce the dataset before left join
   --The order of Inner joins also matters, most restrictive one 
   --should be performed first, you can add more subqueries to make the order explicit
  select a.key, ...
  from a
  join b on a.key=b.key
  join c on a.key=c.key
  )s --subquery with inner joins will be executed before left join
  left join u on s.key=u.key

还可以在单​​个顶点上组合和执行 Map 连接。阅读 .

是的,它们是等价的,尽管结果在结果集中的顺序可能不同。如果您使用 select *,那么列的顺序将不同。

原因有点微妙——外部连接的 table 没有在 FROM 子句的其他任何地方使用。因此,您不必担心来自不匹配行的 NULL 值。

作为一般规则,我在 FROM 子句中对连接进行排序,从内部连接开始,然后是外部连接。当您开始混合连接类型时,该子句变得很难准确遵循。所以,我推荐:

from a join
     b
     on a.key = b.key join
     c
     on a.key = c.key left join
     u
     on a.key = u.key