Hive - Is there a way to further optimize a HiveQL query?

前端 未结 4 744
梦毁少年i
梦毁少年i 2021-01-15 11:56

I have written a query to find 10 most busy airports in the USA from March to April. It produces the desired output however I want to try to further optimize it.

Ar

相关标签:
4条回答
  • 2021-01-15 12:20

    I don't think GROUPING SETS are applicable here because you are only grouping by one field.

    From Apache Wiki: "The GROUPING SETS clause in GROUP BY allows us to specify more than one GROUP BY option in the same record set."

    0 讨论(0)
  • 2021-01-15 12:25

    It might help if you do the aggregation before the union all:

    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;
    
    0 讨论(0)
  • 2021-01-15 12:32

    Filter by airport(inner join) and do aggregation before UNION ALL to reduce dataset passed to the final aggregation reducer. UNION ALL subqueries with joins should run in parallel and faster than join with bigger dataset after 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
    ;
    

    Tune mapjoins and enable parallel execution:

    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
    

    Use Tez and vectorizing, tune mappers and reducers parallelism: https://stackoverflow.com/a/48487306/2700344

    0 讨论(0)
  • 2021-01-15 12:33

    You can test this but you are in the case where an Union maybe better, so You really need to test it and come back :

    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
    
    0 讨论(0)
提交回复
热议问题