sql - 在这种情况下我应该使用子查询吗?
问题描述
我正在使用 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;
解决方案
第二个查询(涉及子查询)可能性能更高。这是基于 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 完成得更快。
推荐阅读
- rx-java - RxJava 2 相当于 Observable.from(Iterable).firstOrDefault?
- angular - 防止在 EF 迁移上启动 Angular
- r - 如何获取 auto.arima 中使用的模型的顺序?
- java - 将jetty插件替换为gretty插件gradle时出错
- environment - drc 包的 mselect 函数在函数内部不起作用
- ffmpeg - FFmpeg 使用来自一个源(实时源)的多个流创建多播
- r - 基于其他三个变量创建二进制文件
- python - 全局变量python,不运行
- perl - 在 Perl 中对日期时间字符串的 hashof 数组进行排序
- mysql - 如何使用换行符显示从数据库中检索的文本?