首页 > 解决方案 > Hive 连接查询优化

问题描述

Table A
---------
col1, col2,Adate,qty

Table B
-------
col2,cost,Bdate

表格大小如下:

A: 100 万 B: 700k

考虑这个查询:

SELECT 
  A.col1,
  A.col2,
  B.Bdate bdate,
  SUM(qty)*COLLECT_LIST(cost)[0] price 
FROM A 
JOIN B 
ON (A.col2 = B.col2 AND A.Adate <= B.Bdate) 
GROUP BY 
  A.col1,
  A.col2,
  B.bdate;

上面的 hive 查询在 4 个从属设备(8GB 内存,100 GB 磁盘)和 1 个主设备(16 GB 内存,100 GB 磁盘)的集群上耗时超过 3 小时

这个查询可以优化吗?如果是,哪里可以优化?

标签: optimizationhivebigdataquery-optimizationhiveql

解决方案


我将尝试为您提供一些建议,以提高Hive.

  • 检查您正在使用的执行引擎
set hive.execution.engine;

如果你的执行引擎是 mr,而不是MapReduce,你可以使用Apache Sparkor Apache Tez,两者都比MapReduce.

set hive.execution.engine=tez;
  • 联接查询的计算量很大并且速度可能很慢,尤其是在联接三个或更多表时,或者在处理非常大的数据时。

可用于解决此问题的一种策略是预先连接数据并将预连接的结果存储在单独的表中,然后您可以对其进行查询。这是对规范化数据库进行非规范化的一种方法,可以更轻松地运行分析查询。这种预连接表的方法有一些成本,但它可以使分析查询更易于编写和运行更快。

还有一些其他技术可以提高Hive查询性能

  • 连接表排序(最大表最后)

与任何类型的调整一样,了解系统的内部工作非常重要。Hive 在执行连接时,需要选择流式传输哪个表以及缓存哪个表。Hive 将 JOIN 语句中的最后一个表用于流式传输,因此我们需要确保此流式传输表是两者中最大的。

A: 100 万 B: 700k

因此,当这两个表连接时,较大的表在查询中排在最后是很重要的。

  • 分桶将数据存储在单独的文件中,而不是像分区这样的单独的子目录。

它以有效的随机方式划分数据,而不是像分区那样以可预测的方式划分数据。当记录被插入分桶表时,Hive 计算指定分桶列中值的哈希码,并使用这些哈希码将记录划分为桶。出于这个原因,分桶有时被称为散列分区。分桶的目标是将记录均匀地分布在预定义数量的桶中。如果所有连接的表都在连接键列上进行分桶,则分桶可以提高连接的性能。

有关分的更多信息,请参阅Hive描述分桶表的语言手册页面,

分桶表

蜂巢中的桶

分区

  • 分区是一种根据日期、城市和部门等特定列的值将表划分为相关部分的方法。

配置单元中的每个表都可以具有一个或多个分区键来标识特定分区。使用分区很容易对数据切片进行查询。

apache-hive-分区


推荐阅读