比较 Hive 查询与不同连接顺序的效率

Posted

技术标签:

【中文标题】比较 Hive 查询与不同连接顺序的效率【英文标题】:Comparing efficiency of Hive queries with different join orders 【发布时间】:2020-12-10 15:29:05 【问题描述】:

考虑 Hive 中的以下两个查询:

SELECT
    *
FROM
    A
INNER JOIN 
    B
INNER JOIN
    C
ON 
    A.COL = B.COL
AND A.COL = C.COL

SELECT
    *
FROM
    A
INNER JOIN
    B
ON
    A.COL = B.COL
INNER JOIN
    C
ON
    A.COL = C.COL

问题:这两个查询在计算上是相同的还是不同的?换句话说,为了获得最快的结果,我应该更喜欢写一个而不是另一个,还是没关系?谢谢。

【问题讨论】:

【参考方案1】:

在 Hive 1.2 上,也在 Hive 2.3 上测试过,都在 Tez 上,优化器足够智能,可以导出与表 B 连接的 ON 条件,并执行两个 INNER JOIN,每个都具有正确的自己的 ON 条件。

检查简单查询

with A as (
select stack(3,1,2,3) as id
),
B as (
select stack(3,1,2,3) as id
),
C as (
select stack(3,1,2,3) as id
)

select * from A 
inner join B
inner join C
ON A.id = B.id AND A.id = C.id

Explain 命令显示两个连接都在单个映射器上作为 map-join 执行,并且每个连接都有自己的连接条件。这是解释输出:

地图 1 文件输出运算符 [FS_17] 映射连接运算符 [MAPJOIN_27](行数=1 宽度=12) 条件:FIL_24.col0=RS_12.col0(Inner),FIL_24.col0=RS_14.col0(Inner),HybridGraceHashJoin:true,Output:["_col0"," _col1","_col2"]

首先我认为它会在第一个查询中与表 B 交叉连接,然后与 C 连接会减少数据集,但两个查询的工作方式相同(相同的计划,相同的执行),这要感谢优化器。

此外,我在关闭 map-join (set hive.auto.convert.join=false;) 的情况下进行了相同的测试,并且两个查询的计划也完全相同。我没有为非常大的桌子测试它,你最好仔细检查一下。

因此,在 Hive 1.2 和 Hive 2.3 上,对于 reducer 上的 map-join 和 merge join,计算上都是相同的

【讨论】:

@AbhishekParab 使用子查询加入表,这首先减少了数据集,然后第二次加入将在较小的数据集上工作,并且可能更快。只有子查询可以帮助订购连接

以上是关于比较 Hive 查询与不同连接顺序的效率的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Hadoop Hive 中执行“事件顺序”查询?

重写连接查询

Hive 多次与自身连接表

0762-5.16.2-Impala查询HBase表字段顺序不正确异常分析

使用 Hive 查询 Sqoop 到 MySQL

SparkSQL 中的表连接顺序以获得更好的性能