首页 > 解决方案 > 在这种情况下我应该使用子查询吗?

问题描述

我正在使用 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零件SELECTGROUP 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;

标签: sqlhive

解决方案


第二个查询(涉及子查询)可能性能更高。这是基于 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 完成得更快。


推荐阅读