我有一个包含4列的表,其中col4作为配置单元中的分区列。这是一个巨大的表,每5小时插入约9米行。我有一个限制,我不能更改此表的设计,因为它也用于其他报表。
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;
问题:
在分区列上执行groupby会影响性能吗?这里是col4。
当我在col4上进行分组时,它仍然是一个完整的表扫描吗?
用最少的全表扫描在分区列上创建查找的最佳方法是什么?
我看到了这个帖子,但它是给 Impala 的。我不确定impala和hive是否在内部使用相同的mr引擎进行数据处理。所以把这个作为一个新问题发布。
1条答案
按热度按时间pkln4tw61#
打开Map器端聚合以获得最佳性能:
set hive.map.aggr=true;
并比较了分区列和非分区列的性能。在分区列的情况下,数据已经部分分组(文件属于单个分区),Map端聚合将执行得更快一些,因为Map程序将为每个列创建更少的组,并且将更少的数据传递给缩减器。换句话说,执行聚合所需的所有记录都在单个分区内,并且每个文件只包含一个组(如果按非分区列分组,则也包含少数组)。但是过度分区可能会导致文件过多和性能下降。如果您的查询需要完全扫描,为什么不应该是完全扫描?是的,它肯定是完全扫描,因为您没有where子句,并且选择的不仅仅是分区列。
全表扫描意味着没有分区修剪。在分区列上添加where条件以限制分区。如果您在查询中只使用分区列,从技术上讲,它只能使用元数据,但这种情况很少见,与您的查询不同。
如果在where子句中使用partition,那么分区的好处最大。
在加载压缩文件和orc表时使用分区和distribute+sort,可以显著减少压缩文件的大小(2倍甚至更多),但我从未注意到它带来了显著的性能提升。