如何解决OR 目前在 Hive 中的 JOIN 错误中不受支持
我正在 Hive 中运行一个查询,如下所示,并且在左连接中有 OR 条件。当我运行选择时,它会向我抛出几条错误消息。
-
OR 目前在 JOIN 中不受支持(了解 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,'')
or translate(a.seller,'Z','') = translate(b.seller,'')
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,'') or a.item_cd = b.item_cd
where a.seller is null
我们如何克服这个问题?
#对于 1: 我可以尝试编写查询的一种方法是,使用 UNION,将查询复制 3 次,用于 OR 条件。
#For 2:
如果我剪了
and a.cre_timestamp < c.cre_timestamp
and a.cre_timestamp > date_sub(c.cre_timestamp,21)
并将其放入底部的 where
子句中,它工作正常。 (想了解为什么它在连接中不起作用)
总的来说,寻找更好的方法,不会影响运行时和更优化的查询,就像我将其更改为使用UNION一样,它必须处理相同的查询3次,这会影响查询.
感谢您花时间研究这个问题。
解决方法
我已经在这篇文章中解释过为什么非等 (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 子查询将允许读取表一次(在映射器上),所有其他顶点将读取由映射器准备的相同结果,从而避免每次将中间结果写入持久性存储。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。