首页 > 解决方案 > Group By 在 Hive 中的分区列上的性能

问题描述

我有一个包含 4 列的表,其中 col4 作为 Hive 中的分区列。这是一个巨大的表,每 5 小时插入约 900 万行。我有一个限制,我不能更改此表的设计,因为它也用于其他报告。

CREATE EXTERNAL TABLE testdb.table1(col1 string, col2 int, col3 int)
PARTITIONED BY (col4 string)
ROW FORMAT DELIMITED
STORED AS TEXTFILE
LOCATION '/path/to/input/';

对于其中一个用例,我正在尝试创建一个查找表来识别 col4 中每个值的一些数据点,例如

select col1, col4 from testdb.table1 group by col1, col4;

问题:

  1. 对分区列执行 Group By 会影响性能吗?Col4 在这种情况下。

  2. 当我在 col4 上进行 Group By 时,它仍然是全表扫描吗?

  3. 在具有最少全表扫描的分区列上创建查找的最佳方法是什么?

我遇到了这篇文章,但它是给 Impala 的。我不确定 Impala 和 Hive 是否在内部使用相同的 MR 引擎进行数据处理。因此,将此作为一个新问题发布。

标签: hadoophiveclouderahive-partitions

解决方案


  1. 打开映射器端聚合以获得最佳性能:

set hive.map.aggr=true;

并将性能与分区和非分区列进行比较。在分区列的情况下,数据已经部分分组(文件属于单个分区)并且映射端聚合将执行得更快一些,因为映射器将创建更少的组,并且更少的数据将传递给减速器。换句话说,执行聚合所需的所有记录都在单个分区内,并且每个文件仅包含一个组(如果按非分区列分组,则很少有组)。但是过度分区可能会导致文件过多和性能下降。

  1. 如果您的查询需要完整扫描,为什么不应该是完整扫描?是的,它肯定会是全扫描,因为您没有 WHERE 子句并且不仅选择分区列。

  2. 全表扫描意味着没有分区修剪。在分区列上添加 WHERE 条件以限制分区。如果您在查询中仅使用分区列,从技术上讲,它只能使用元数据,但这种情况很少见,与您的查询不同。

如果您在 WHERE 子句中使用分区,则可以从分区中获益。

在加载压缩表和 ORC 表时使用分区和 DISTRIBUTE+SORT 可以显着减小压缩文件的大小(2 倍甚至更多),但我从未注意到它带来了显着的性能提升。


推荐阅读