对行进行排序时优化 Hive GROUP BY
Posted
技术标签:
【中文标题】对行进行排序时优化 Hive GROUP BY【英文标题】:Optimizing Hive GROUP BY when rows are sorted 【发布时间】:2016-12-20 17:15:48 【问题描述】:我有以下(非常简单的)Hive 查询:
select user_id, event_id, min(time) as start, max(time) as end,
count(*) as total, count(interaction == 1) as clicks
from events_all
group by user_id, event_id;
表格结构如下:
user_id event_id time interaction
Ex833Lli36nxTvGTA1Dv juCUv6EnkVundBHSBzQevw 1430481530295 0
Ex833Lli36nxTvGTA1Dv juCUv6EnkVundBHSBzQevw 1430481530295 1
n0w4uQhOuXymj5jLaCMQ G+Oj6J9Q1nI1tuosq2ZM/g 1430512179696 0
n0w4uQhOuXymj5jLaCMQ G+Oj6J9Q1nI1tuosq2ZM/g 1430512217124 0
n0w4uQhOuXymj5jLaCMQ mqf38Xd6CAQtuvuKc5NlWQ 1430512179696 1
我知道行首先按user_id
排序,然后按event_id
排序。
问题是:如果行已排序,有没有办法“提示”Hive 引擎来优化查询?优化的目的是避免将所有组保留在内存中,因为一次只需要保留一个组。
目前,在包含大约 300 GB 数据的 6 节点 16 GB Hadoop 集群中运行此查询大约需要 30 分钟,并且使用了大部分 RAM,导致系统阻塞。我知道每个组都会很小,每个 (user_id, event_id)
元组不超过 100 行,所以我认为优化的执行可能会占用非常小的内存并且速度更快(因为不需要循环组键)。
【问题讨论】:
附带说明,count(interaction == 1)
没有按我的预期工作,只计算具有 1 的行,而是返回与 count(*)
相同的行。
是的。聚合函数,包括 COUNT,忽略(仅)NULL 值并且 FALSE 不是 NULL
【参考方案1】:
创建一个分桶排序表。优化器会知道它是从元数据中排序的。 请参阅此处的示例(官方文档):https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-BucketedSortedTables
Count only interaction = 1:count(case when interaction=1 then 1 end) as clicks
- case 会将所有行标记为 1 或 null,并且只计算 1。
【讨论】:
感谢@leftjoin。有几件事:首先,我的表是一个外部表,有没有办法让它工作?其次,由于它是一个外部表,因此格式是固定的(制表符分隔值,\n 终止行),并且它没有不同的组终止符等。如果问的不多,您能否提供一个使用示例我发布的具体结构? @Alejandro Piad 另请阅读:grokbase.com/t/hive/user/133xgs10cb/bucketing-external-tables 很抱歉,您似乎必须创建分桶表并插入覆盖它,如果您在现有文本文件上创建外部表,它将无法正常工作。而且移动数据需要很长时间。 是的@leftjoin,我读过的所有内容都指向这一点。我接受这是正确的答案。以上是关于对行进行排序时优化 Hive GROUP BY的主要内容,如果未能解决你的问题,请参考以下文章
使用Order By NULL 解决 group by后自动排序,优化Sql性能