Оптимизировать длительный SQL-запрос куста - имеет соединение с той же таблицей

Приведенный ниже запрос занимает много времени. Он работает с двигателем исполнения Tez.

SELECT STG.EMP_TYPE, DEPT, A.TOTAL_COUNT, COUNT(DISTINCT EMP_ID) AS COUNT_DEPT
FROM 
STAGE_SOURCE STG 
LEFT OUTER JOIN 
( SELECT EMP_TYPE, COUNT(DISTINCT EMP_ID) AS TOTAL_COUNT 
  FROM STAGE_SOURCE 
  GROUP BY EMP_TYPE 
) A
ON STG.EMP_TYPE = A.EMP_TYPE
GROUP BY STG.EMP_TYPE, DEPT, A.TOTAL_COUNT;

Есть ли какая-либо опция перезаписи или стратегия оптимизации, которая может улучшить производительность запроса?

2 ответа

Поняв ваш запрос, я смог понять, что вам нужно количество значений 2. Во-первых, количество EMP_ID для каждого EMP_TYPE и, во-вторых. Количество EMP_ID в DEPT & EMP_TYPE

SELECT 

STG.EMP_TYPE, 
DEPT,
TOTAL_COUNT, 
COUNT(EMP_ID) AS COUNT_DEPT

FROM 
STAGE_SOURCE STG 
JOIN 
( SELECT EMP_TYPE, COUNT(EMP_ID) AS TOTAL_COUNT 
  FROM STAGE_SOURCE 
  GROUP BY EMP_TYPE 
) A
ON STG.EMP_TYPE = A.EMP_TYPE
GROUP BY STG.EMP_TYPE, DEPT,TOTAL_COUNT;

Использование GROUP BY вместо DISTINCT, где это возможно, может сократить время выполнения. Как уже упоминалось выше в разделе "Учитывайте меня", GROUP BY использует преимущества индексов.

Я бы порекомендовал получать записи таблицы только один раз.

Ваше внутреннее совокупное вычисление может быть сделано с использованием оконной функции.

Я считаю, что этот запрос должен дать вам те же результаты, и вы бы избавились от JOIN,

SELECT
    EMP_TYPE,
    DEPT,
    COUNT( DISTINCT EMP_ID ) OVER ( PARTITION BY EMP_TYPE ) AS TOTAL_COUNT,
    COUNT( DISTINCT EMP_ID ) AS COUNT_DEPT
FROM
    STAGE_SOURCE
GROUP BY EMP_TYPE, DEPT

Помните, что GROUP BY также можете воспользоваться индексами.

Вот ссылка на руководство Apache Hive о функциях управления окнами и аналитики

# Редактировать после вашего комментария

По крайней мере в PostgreSQL пункт DISTINCT применяется после вычислений агрегатов оконной функции, что приводит нас к небольшому эксплойту, который может дать вам то, что вам нужно. Таким образом, мы избавились от GROUP BY, Посмотрите, как это работает на Postgres: SQLFiddle

Попробуйте следующий запрос:

SELECT
    DISTINCT
    EMP_TYPE,
    DEPT,
    COUNT( DISTINCT EMP_ID ) OVER ( PARTITION BY EMP_TYPE ) AS TOTAL_COUNT,
    COUNT( DISTINCT EMP_ID ) OVER ( PARTITION BY EMP_TYPE, DEPT ) AS COUNT_DEPT
FROM
    STAGE_SOURCE

# Редакция 2

SELECT
    DISTINCT
    EMP_TYPE,
    DEPT,
    COUNT( DISTINCT EMP_ID ) OVER ( PARTITION BY EMP_TYPE ) AS TOTAL_COUNT,
    COUNT( DISTINCT EMP_ID ) OVER ( PARTITION BY EMP_TYPE, DEPT ) AS COUNT_DEPT
FROM (
    SELECT DISTINCT EMP_TYPE, DEPT, EMP_ID FROM STAGE_SOURCE
    ) foo
Другие вопросы по тегам