Hive:在连接之前在子表中使用 where 子句是不是会提高性能?

Posted

技术标签:

【中文标题】Hive:在连接之前在子表中使用 where 子句是不是会提高性能?【英文标题】:Hive: Is there a performance improvement of using where clause in subtables before joins?Hive:在连接之前在子表中使用 where 子句是否会提高性能? 【发布时间】:2016-10-26 16:18:34 【问题描述】:

我想加入 2 个蜂巢表。以下语句之间是否存在性能差异?

basic_info 的列:用户 ID、姓名、姓氏、生日、职业

account_info 的列:user_id、account_id、类型、余额

查询1:

SELECT b.user_id, a.account_id, b.name, b.lastname, a.balance
FROM account_info a
JOIN basic_info b
   ON a.user_id = b.user_id
WHERE b.occupation = 'lawyer'

查询2:

SELECT b.user_id, a.account_id, b.name, b.lastname, a.balance
FROM account_info a
JOIN 
   (SELECT user_id, name, lastname 
    FROM basic_info
    WHERE occupation = 'lawyer') b
   ON a.user_id = b.user_id

对我来说,第二个看起来更高效。但我找不到一个明显的说法。我在 Apache 的网站上找到的最接近的东西是:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Joins

连接发生在 WHERE 子句之前。因此,如果要限制连接的输出,则应在 WHERE 子句中提出要求,否则应在 JOIN 子句中。这个问题的一大困惑点是分区表。

但是给出的示例是针对分区而不是针对这种情况的。是否有官方文件表明 Query 2 更好?

【问题讨论】:

这两个查询的执行时间是多少?这应该是回答您问题的一种可衡量的方式。 mysql 或 oracle 等现代关系数据库上,这两个查询应该生成完全相同的执行计划。通常选择发生在加入之前。我不确定 Hive。最好是尝试查看实际的执行计划。 【参考方案1】:

是的,Query-2 应该运行得很快。正如您所提到的,join 发生在 where 子句之前。

但是对于您在官方文件上的问题- Hive 中有一个谓词下推选项。默认情况下,此选项设置为 false。可以使用

将其设置为 true

设置 hive.optimize.ppd=true;

当此选项设置为 true 时,连接发生在 where 子句之后。在您的情况下,如果您将此属性设置为“True”,则您的两个查询应同时完成。当属性设置为 false(默认行为)时,查询 2 应该很快完成。

由于 HIVE 有一个明确的谓词下推属性,我们可以得出结论,当该属性设置为 false 时,Join 发生在 where 子句之前。

【讨论】:

默认情况下为年龄启用谓词推送 hive.optimize.ppd 默认值:true 已添加:具有 HIVE-279 的 Hive 0.4.0,在具有 HIVE-626 的 Hive 0.4.0 中默认更改为 true是否启用谓词下推 (PPD)。【参考方案2】:

这个sql有多种写法。虽然,您的两个查询都返回相同的输出,但内部执行计划不同,并且执行时间可能有显着差异。 Hive explain command 是开始调试和了解幕后查询执行计划的好点。我希望解释命令能帮助你弄清楚这两个命令之间的区别。

其他因素,Hive Map Joins and SMB(Sort-Merge-Bucket) 提高连接效率。

【讨论】:

以上是关于Hive:在连接之前在子表中使用 where 子句是不是会提高性能?的主要内容,如果未能解决你的问题,请参考以下文章

在子查询中为数据透视列的值实现 WHERE 子句?

oracle查询包含在子表中的主表数据

Hive Query 不允许 >= 在 where 子句的子查询中

在子查询中使用内联函数(在 WHERE 子句中)

使用 WHERE 子句的查询不起作用

在子表中没有记录的“周”之间查询多条记录