或者 Hive 中的 JOIN 错误当前不支持
Posted
技术标签:
【中文标题】或者 Hive 中的 JOIN 错误当前不支持【英文标题】:OR not supported currently in JOIN error in Hive 【发布时间】:2021-01-15 20:07:12 【问题描述】:我正在 Hive 中运行一个查询,如下所示,并且在左连接中有 OR 条件。当我运行选择时,它会抛出一些错误消息。
目前在 JOIN 中不支持 OR(了解 OR 仅适用于 Hive 中的 equi 联接)
在 JOIN 'cre_timestamp' 中遇到左右别名
a.line_id,
a.seller,
a.sellerid,
a.sellername,
a.item_no,
a.item_cd,
a.cre_timestamp
from Table A
left join Table B
on translate(a.id,'0','') = translate(b.id,'0','')
or translate(a.seller,'Z','') = translate(b.seller,'Z','')
or (a.item_no=b.item_no and a.item_no is not null and a.item_cd is not null and a.item_no <> '' and a.item_cd <> '')
left join ( select id, line_id,cre_timestamp from table x) C
on a.id=c.id
and a.cre_timestamp < c.cre_timestamp
and a.cre_timestamp > date_sub(c.cre_timestamp,21)
and translate(a.id,'0','') = translate(b.id,'0','') or a.item_cd = b.item_cd
where a.seller is null
我们如何克服这个问题?
#对于 1: 我可以尝试编写查询的一种方法是,使用 UNION 将查询复制 3 次,用于 OR 条件。
#2:
如果我剪掉了
and a.cre_timestamp < c.cre_timestamp
and a.cre_timestamp > date_sub(c.cre_timestamp,21)
并将其放入底部的where
子句中,它可以正常工作。 (想了解为什么它在连接中不起作用)
总的来说,寻找更好的方法,不会影响运行时和更优化的查询,如果我将它更改为使用UNION,它必须处理相同的查询3次,这会影响查询.
感谢您抽出宝贵时间对此进行调查。
【问题讨论】:
【参考方案1】:我已经在这篇文章中尝试解释了为什么非 equi (theta) 连接在 map-reduce 框架中不起作用,这里不再重复,请阅读:Why Hive can not support non-equi join
现在,如果将非相等连接条件移至 where 子句会发生什么情况:连接将仅使用相等条件工作,并且可能会产生一些重复,因为它可能是多对多连接。这些重复项将按 WHERE 条件过滤。在最坏的情况下,如果你根本没有相等条件,就会执行 CROSS JOIN,这也很容易使用 MapReduce 框架实现,之后你可以过滤 where 中的行。过滤也很容易实现。
这是目前在 Hive 中实现 Theta-join 的唯一方法:在部分相等条件(甚至 CROSS JOIN)上使用复制连接加上过滤,这种方法会对性能产生重大的负面影响。但是,如果其中一张表足够小以适合内存,您可以使用 map-join 补偿对性能的负面影响:
set hive.auto.convert.join=true;
set hive.mapjoin.smalltable.filesize=1000000000; --small table size which can fit in memory,
--adjust it and check Map Join operator in the plan
另外(这与问题无关)您的查询中有多余的条件:
(a.item_no=b.item_no and a.item_no is not null and a.item_cd is not null and a.item_no <> '' and a.item_cd <> '')
a.item_no is not null
- 在这里没有任何用处,因为 1) 此列已在相等连接条件中使用并且 NULL 未连接,2) 还有另一个条件 a.item_no <> ''
不包括 NULL,因为如果值不等于空字符串,它也不能为 NULL,NULL 不能等于或不等于某物。
同样的冗余条件a.item_cd is not null
,因为你已经有a.item_cd <> ''
,这不允许NULL。
所以,整个条件可以简化为这个:
(a.item_no=b.item_no and a.item_no <> '' and a.item_cd <> '')
是的,将查询拆分为两个或多个 + UNION 是解决 OR 连接条件问题的常用方法。如果你有一些常用的过滤器,可以使用WITH
子查询来补偿多次扫描整个表。使用不同的过滤器和连接条件 + UNION 或 UNION ALL 拆分数据集也有助于处理倾斜的连接键。如果您使用的是 Tez,使用 WITH 子查询将允许读取一次表(在映射器上),所有其他顶点将读取映射器准备的相同结果,从而消除了每次将中间结果写入持久存储。
【讨论】:
感谢您的详细解释。我将测试上述条件,看看它是如何工作的。以上是关于或者 Hive 中的 JOIN 错误当前不支持的主要内容,如果未能解决你的问题,请参考以下文章