Должен ли я использовать подзапрос в этой ситуации? - PullRequest
0 голосов
/ 04 мая 2018

Я использую 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;

Ответы [ 3 ]

0 голосов
/ 04 мая 2018

Оператор 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
;
0 голосов
/ 04 мая 2018

Второй запрос (включающий подзапрос) может быть более производительным. Это основано на интерпретации из плана объяснения 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 выполняется быстрее во всех случаях.

0 голосов
/ 04 мая 2018

Расходы на агрегацию включают чтение большого количества данных. Затем либо сортируйте его, либо хэшируйте, чтобы соединить ключи. Затем двигатель должен обработать данные и рассчитать количество.

То, вызывается ли выражение case один или два раза, довольно бессмысленно в контексте всего перемещения данных. Не беспокойся об этом. Если есть дополнительная работа, она тривиальна по сравнению со всем остальным, что нужно сделать для запроса.

Я также думаю, что Hive поддерживает псевдонимы столбцов в GROUP BY, но я могу ошибаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...