Table A
---------
col1, col2,Adate,qty
Table B
-------
col2,cost,Bdate
表大小如下:
a:100万b:70万
考虑以下问题:
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;
上面的配置单元查询在由4个从属(8gb内存,100GB磁盘)和1个主(16GB内存,100GB磁盘)组成的集群上需要3个多小时
这个查询可以优化吗?如果是,在哪里可以进行优化?
2条答案
按热度按时间o3imoua41#
使用tez和mapjoin。
此外,这种计算也不节省内存:
j2qf4p5b2#
我将尝试为您提供一些建议,以提高中的查询性能
Hive
.检查正在使用的执行引擎
如果执行引擎是mr,而不是
MapReduce
,您可以使用Apache Spark
或者Apache Tez
,两者都比MapReduce
.连接查询的计算代价很高,而且速度很慢,特别是在连接三个或更多表时,或者在处理非常大的数据时。
可以用来解决这个问题的一种策略是提前连接数据,并将预连接的结果存储在一个单独的表中,然后您可以查询这个表。这是对规范化数据库进行反规范化的一种方法,以使运行分析查询更容易。这种预联接表的方法有一定的成本,但它可以使分析查询更易于编写和运行。
还有一些其他的技术可以改进
Hive
查询性能联接表排序(最后一个最大的表)
与任何类型的调整一样,了解系统的内部工作非常重要。当配置单元执行连接时,它需要选择哪个表被流化,哪个表被缓存。hive将join语句中的最后一个表用于流式处理,因此我们需要确保这个流式处理表在这两个表中是最大的。
a:100万b:70万
因此,连接这两个表时,较大的表在查询中排在最后是很重要的。
bucketing将数据存储在单独的文件中,而不是像分区那样的单独子目录。
它以一种有效的随机方式划分数据,而不是像划分那样以一种可预测的方式。当记录被插入到一个bucketed表中时,hive计算指定bucketing列中的值的散列码,并使用这些散列码将记录分成bucket。因此,bucketing有时被称为hash分区。bucketing的目标是将记录均匀地分布在预定义数量的bucket上。如果所有联接的表都在联接键列上扣接,扣接可以提高联接的性能。
有关扣合的更多信息,请参阅
Hive
语言手册,描述带扣的表格,扣板
Hive中的木扣
分区
分区是一种基于特定列(如date、city和department)的值将表划分为相关部分的方法。
配置单元中的每个表都可以有一个或多个分区键来标识特定的分区。使用分区可以很容易地对数据片段进行查询。
apache hive分区