optimization - 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 小时
这个查询可以优化吗?如果是,哪里可以优化?
解决方案
我将尝试为您提供一些建议,以提高Hive
.
- 检查您正在使用的执行引擎
set hive.execution.engine;
如果你的执行引擎是 mr,而不是MapReduce
,你可以使用Apache Spark
or Apache Tez
,两者都比MapReduce
.
set hive.execution.engine=tez;
- 联接查询的计算量很大并且速度可能很慢,尤其是在联接三个或更多表时,或者在处理非常大的数据时。
可用于解决此问题的一种策略是预先连接数据并将预连接的结果存储在单独的表中,然后您可以对其进行查询。这是对规范化数据库进行非规范化的一种方法,可以更轻松地运行分析查询。这种预连接表的方法有一些成本,但它可以使分析查询更易于编写和运行更快。
还有一些其他技术可以提高Hive
查询性能
- 连接表排序(最大表最后)
与任何类型的调整一样,了解系统的内部工作非常重要。Hive 在执行连接时,需要选择流式传输哪个表以及缓存哪个表。Hive 将 JOIN 语句中的最后一个表用于流式传输,因此我们需要确保此流式传输表是两者中最大的。
A: 100 万 B: 700k
因此,当这两个表连接时,较大的表在查询中排在最后是很重要的。
- 分桶将数据存储在单独的文件中,而不是像分区这样的单独的子目录。
它以有效的随机方式划分数据,而不是像分区那样以可预测的方式划分数据。当记录被插入分桶表时,Hive 计算指定分桶列中值的哈希码,并使用这些哈希码将记录划分为桶。出于这个原因,分桶有时被称为散列分区。分桶的目标是将记录均匀地分布在预定义数量的桶中。如果所有连接的表都在连接键列上进行分桶,则分桶可以提高连接的性能。
有关分桶的更多信息,请参阅Hive
描述分桶表的语言手册页面,
分区
- 分区是一种根据日期、城市和部门等特定列的值将表划分为相关部分的方法。
配置单元中的每个表都可以具有一个或多个分区键来标识特定分区。使用分区很容易对数据切片进行查询。
推荐阅读
- spring-mvc - 使用 Spring Web Flow 上传文件
- vb.net - 使用子字符串在字符串中拆分日期和时间
- ubuntu - 在 Ubuntu 上阻止 ASN 而不是 IP/CIDR
- jquery - 使用 .html() 未显示图标
- php - 如何使用 PHP 从 JSON 中获取最后 5 个数据?
- python - 如何从值为“No”而不是 NaN 的列中清除值?
- matlab - 在 Win10 上为 MATLAB 编译 SPAMS 工具箱时出现“未声明的 '_finite'”错误
- grails - Grails Spring Security Shiro,如何在无需注销重新登录的情况下刷新权限?
- julia - 如何计算我的主要代码的时间?
- android - How can I use Android expansion files using App Bundle?