[Hive]Hive中表連線的優化,加快查詢速度

TOMOCAT發表於2018-08-15

1、多表連線的執行順序和MapReduce job優化

select
    a.ymd
    ,a.price_close
    ,b.price_close
    ,c.price_close
from stocks a join stocks b on a.ymd = b.ymd
              join stocks c on a.ymd = c.ymd
where a.symbol = 'APPL' and b.symbol = 'IBM' and c.symbol = 'GE'

 

大多數情況下Hive會對每對 JOIN 連線物件啟動一個MapReduce任務。上例中會首先啟動一個MapReduce job對錶 a 和表 b 進行連線操作,
然後會啟動一個MapReuce job將第一個MapReduce job的輸出和表 c 進行連線操作。

當對3個或者更多個表進行 JOIN 連線時,如果每個 ON 子句都使用相同的連線鍵的話,那麼只會產生一個 Map Reduce job。
即Hive通過一個優化可以在同一個Map Reduce job 中連線多個表(需要每個子句中有相同的連線鍵)。

2、JOIN連線時表的順序(內連線)
Hive假定查詢中最後一個表是最大的那個表,在對每行記錄進行連線操作時,它會嘗試將其他表快取起來,然後掃描最後那個表進行計算。
因此使用者需要保證連續查詢中表的大小從左往右是依次增加的。

使用者也可以人為顯示告訴查詢優化器哪張表是大表,即使它在查詢中不是位於最後面的,使用方式如下:

select /*+STREAMTABLE(s)*/s.ymd, s.symbol,s.price_close,d.dividend
from stocks s JOIN dividends d ON s.ymd = d.ymd and s.symbol = d.symbol
where s.symbol='APPL'

3、連線前通過WHERE過濾資料加快查詢資料
最直接了當的方式是使用巢狀SELECT語句:

select 
    s.ymd,s.symbol,s.price_close,d.dividends 
from 
    (
        select * from stocks 
        where symbol = 'AAPL' and exchange = 'NASDAQ'
    )s
left outer join
    (
        select * from dividends 
        where symbol = 'AAPL' and exchange = 'NASDAQ'
    )d
on s.ymd = d.ymd

4、map-side JOIN 優化含有小表的連線
如果所有表中只有一張表是小表,則可以在最大的表通過mapper的時候將小表完全放到記憶體中。Hive可以在map端執行連線過程(稱為mao-side JOIN),這是因為
Hive可以和記憶體中的小表逐一匹配,從而省略常規連線操作需要的reduce過程。不僅減少了reduce過程,有時也可以同時減少map過程的執行步驟。

set hive.auto.convert.join=true; --讓Hive在必要的時候啟動優化
hive.mapjoin.smalltable.filesize=25000000; --設定能夠使用這個優化的小表的大小(單位是位元組)

 

相關文章