복붙노트

[HADOOP] 하이브 - HiveQL 쿼리를 더욱 최적화 할 수있는 방법이 있습니까?

HADOOP

하이브 - HiveQL 쿼리를 더욱 최적화 할 수있는 방법이 있습니까?

나는 3 월에서 4 월까지 미국에서 가장 바쁜 10 개의 공항을 찾기 위해 질의를 작성했다. 원하는 출력을 생성하지만 더 이상 최적화하려고합니다.

쿼리에 적용 할 수있는 HiveQL 특정 최적화가 있습니까? 여기에 GROUPING SETS를 적용 할 수 있습니까? 저는 Hive에 익숙하지 않습니다. 그리고 지금은 이것이 제가 생각해 낸 가장 짧은 쿼리입니다.

SELECT airports.airport, COUNT(Flights.FlightsNum) AS Total_Flights
FROM (
SELECT Origin AS Airport, FlightsNum 
  FROM flights_stats
  WHERE (Cancelled = 0 AND Month IN (3,4))
UNION ALL
SELECT Dest AS Airport, FlightsNum 
  FROM flights_stats
  WHERE (Cancelled = 0 AND Month IN (3,4))
) Flights
INNER JOIN airports ON (Flights.Airport = airports.iata AND airports.country = 'USA')
GROUP BY airports.airport
ORDER BY Total_Flights DESC
LIMIT 10;

테이블 열은 다음과 같습니다.

공항

|iata|airport|city|state|country|

Flights_stats

|originAirport|destAirport|FlightsNum|Cancelled|Month|

해결법

  1. ==============================

    1.공항으로 필터링 (내부 조인)하고 UNION ALL 이전에 집계를 수행하여 최종 집계 감속기로 전달 된 데이터 집합을 줄입니다. 조인이있는 UNION ALL 하위 쿼리는 UNION ALL 후에 더 큰 데이터 세트로 조인하는 것보다 병렬로 실행해야합니다.

    공항으로 필터링 (내부 조인)하고 UNION ALL 이전에 집계를 수행하여 최종 집계 감속기로 전달 된 데이터 집합을 줄입니다. 조인이있는 UNION ALL 하위 쿼리는 UNION ALL 후에 더 큰 데이터 세트로 조인하는 것보다 병렬로 실행해야합니다.

    SELECT f.airport, SUM(cnt) AS Total_Flights
    FROM (
          SELECT a.airport, COUNT(*) as cnt 
           FROM flights_stats f
                INNER JOIN airports a ON f.Origin=a.iata AND a.country='USA'
           WHERE Cancelled = 0 AND Month IN (3,4)
           GROUP BY a.airport
           UNION ALL
          SELECT a.airport, COUNT(*) as cnt
           FROM flights_stats f
                INNER JOIN airports a ON f.Dest=a.iata AND a.country='USA'
           WHERE Cancelled = 0 AND Month IN (3,4)
           GROUP BY a.airport
         ) f 
    GROUP BY f.airport
    ORDER BY Total_Flights DESC
    LIMIT 10
    ;
    

    mapjoin을 조정하고 병렬 실행을 활성화합니다.

    set hive.exec.parallel=true;
    set hive.auto.convert.join=true; --this enables map-join
    set hive.mapjoin.smalltable.filesize=25000000; --size of table to fit in memory
    

    Tez을 사용하고 벡터화, 매퍼 및 리듀서 병렬 처리 튜닝 : https://stackoverflow.com/a/48487306/2700344

  2. ==============================

    2.노조 전 집계를 수행하는 것이 도움이 될 수 있습니다.

    노조 전 집계를 수행하는 것이 도움이 될 수 있습니다.

    SELECT a.airport, SUM(cnt) AS Total_Flights
    FROM ((SELECT Origin AS Airport, COUNT(*) as cnt 
           FROM flights_stats
           WHERE (Cancelled = 0 AND Month IN (3,4))
           GROUP BY Origin
          ) UNION ALL
          (SELECT Dest AS Airport, COUNT(*) as cnt
           FROM flights_stats
           WHERE Cancelled = 0 AND Month IN (3,4)
           GROUP BY Dest
          )
         ) f INNER JOIN
         airports a
         ON f.Airport = a.iata AND a.country = 'USA'
    GROUP BY a.airport
    ORDER BY Total_Flights DESC
    LIMIT 10;
    
  3. ==============================

    3.한 필드로만 그룹화하기 때문에 여기서는 GROUPING SETS를 적용 할 수 없다고 생각합니다.

    한 필드로만 그룹화하기 때문에 여기서는 GROUPING SETS를 적용 할 수 없다고 생각합니다.

    Apache Wiki에서 : "GROUP BY의 GROUPING SETS 절을 사용하면 동일한 레코드 세트에서 둘 이상의 GROUP BY 옵션을 지정할 수 있습니다."

  4. ==============================

    4.이것을 테스트 할 수는 있지만 유니온이 더 나을 수도 있습니다. 따라서 테스트를 거쳐 돌아와야합니다.

    이것을 테스트 할 수는 있지만 유니온이 더 나을 수도 있습니다. 따라서 테스트를 거쳐 돌아와야합니다.

    SELECT airports.airport,
    SUM(
      CASE 
         WHEN T1.FlightsNum IS NOT NULL THEN 1
         WHEN T2.FlightsNum IS NOT NULL THEN 1
         ELSE 0
      END 
      ) AS Total_Flights
    FROM airports
    LEFT JOIN (SELECT  Origin AS Airport, FlightsNum 
        FROM flights_stats
       WHERE (Cancelled = 0 AND Month IN (3,4))) t1 
     on t1.Airport = airports.iata
    LEFT JOIN (SELECT Dest AS Airport, FlightsNum 
       FROM flights_stats
       WHERE (Cancelled = 0 AND Month IN (3,4))) t2
     on t1.Airport = airports.iata
    GROUP BY airports.airport
    ORDER BY Total_Flights DESC
    
  5. from https://stackoverflow.com/questions/49153561/hive-is-there-a-way-to-further-optimize-a-hiveql-query by cc-by-sa and MIT license