我正在使用Apache Hive,我有这样的查询:
SELECT CASE type WHEN 'a' THEN 'A'
WHEN 'b' THEN 'B'
ELSE 'C'
END AS map_type
,COUNT(user_id) AS count
FROM user_types
GROUP BY CASE type WHEN 'a' THEN 'A'
WHEN 'b' THEN 'B'
ELSE 'C'
END
;
如您所见,我需要按map_type
字段对结果进行分组,该字段以复杂的方式计算。在我的情况下,CASE WHEN
和SELECT
中的GROUP BY
部分会被计算两次吗?如果我使用下面的子查询,它会更有效吗?
SELECT map_type
,COUNT(user_id) AS count
FROM (
SELECT CASE type WHEN 'a' THEN 'A'
WHEN 'b' THEN 'B'
ELSE 'C'
END AS map_type
,user_id
FROM user_types
) a
GROUP BY map_type;
答案 0 :(得分:1)
第二个查询(涉及子查询)可能更高效。这是基于Hive的解释计划的解释,并运行这些查询几次。
查询1(没有子查询)的解释计划有以下部分:
Group By Operator [GBY_2]
aggregations:["count(user_id)"]
keys:CASE (type) WHEN ('a') THEN ('A') WHEN ('b') THEN ('B') ELSE ('C') END (type: string)
另一方面,查询2(带子查询)的相同部分包含:
Group By Operator [GBY_3]
aggregations:["count(_col1)"]
keys:_col0 (type: string)
根据计划,看起来查询2的工作量略少。
还对虚拟数据进行了测试,并获得了这些执行时间。
Query 1: (1st time) 6.43 s, (2nd time) 5.92 s, (3rd time): 4.30s
Query 2: (1st time) 0.82 s, (2nd time) 1.29 s, (3rd time): 1.03s
查询2在所有情况下都完成得更快。
答案 1 :(得分:0)
进行聚合的费用涉及阅读大量数据。然后对其进行排序或对其进行散列以将密钥组合在一起。然后引擎需要处理数据并计算计数。
在所有数据移动的上下文中,一次或两次调用case
表达式是否毫无意义。别担心。如果有额外的工作,那么与其他需要为查询完成的工作相比,它是微不足道的。
我还认为Hive支持GROUP BY
中的列别名,但我可能会弄错。
答案 2 :(得分:0)
case case语句在你的情况下是无害的,但如果你打算使用子查询可能会增加时间
你可以继续
SELECT CASE type WHEN 'a' THEN 'A'
WHEN 'b' THEN 'B'
ELSE 'C'
END AS map_type
,COUNT(user_id) AS count
FROM user_types
GROUP BY CASE type WHEN 'a' THEN 'A'
WHEN 'b' THEN 'B'
ELSE 'C'
END
;