群裡共享了一本hive調優的書記,名叫《hive tunning》,就忍不住開始看了,也順便記錄一下自己學到的東西,備忘!
首先,這是hive的資料摘要,别問我什麼意思,我也沒看懂。

好,我們正式開始,首先是連接配接的問題,我們都知道連接配接耗時長,但是連接配接無法避免,那hive又是怎麼處理連接配接操作的呢?
下面是hive的連接配接政策:
hive有<b>三種類型的連接配接政策</b>:
(1)shuffle join : 這種類型的是通過map/reduce 來實作連接配接操作的,優點是不需要考慮資料的大小和分布,缺點是消耗大量的資源而且是最慢的。
(2)broadcast join:這種類型的方式是把一個小的表在所有節點中加載到内容當中,然後用mapper來掃描大表進行連接配接,速度非常快,但是其中一個表必須可以加載到記憶體當中。
(3)sort-merge-bucket join:mapper可以協同定位keys去進行高效的連接配接,速度很快,不需要考慮表的大小,但是資料必須先排序和整理。
<b>shuffle join:</b>
我們以這個銷售訂單這個例子來做示範,可以看到其中的圖,它們是通過customer.id=order.cid來做連接配接的,首先map把兩個表中的資料處理成以連接配接字段為key,其他字段為value的作為輸出,然後把兩個表中id和cid相同的資料傳遞到同一個reducer中,從網絡使用率上看是很奢侈的。
<b>broadcast join:</b>
這種方式比較複雜一點,首先它使用足夠小的次元表來存放在所有的節點當中,單獨掃描大表,然後根據模式比對進行連接配接。
當兩個表都很大的情況下:
第一步,首先按照連接配接字段排序,所有可能的比對的都在硬碟的同一塊區域。
第二步,把所有的值都移到同一個節點下面進行等值連接配接,不需要再進行shuffle。
<b>bucketing:</b>
– hash partition values into a configurable number of buckets.
– usually coupled with sorting.
• skews:
– split values out into separate files.
– used when certain values are frequently seen.
• replication factor:
– increase replication factor to accelerate reads.
– controlled at the hdfs layer.
• sorting:
– sort the values within given columns.
– greatly accelerates query when used with orcfilefilter pushdown.
這裡就不解釋了,自己看吧,這和下面的圖是對應的,針對不同大小的表,hive有多種處理模式。
(1)小表,經常要用的資料,建議使用replication factor,可能是緩存的意思,具體是什麼意思,等我清楚了再給大家解釋。
(2)任意大小的表,有很多要精确查詢的列,建議先按照最常使用的列進行排序再進行查詢。
(3)大表但是又需要和另外的的大表做連接配接,建議先通過連接配接列做排序和bucket。
(4)大表,但隻是利用到其中某些常用的值,可以把常用的值弄個單獨的skew中。
(5)大表但是有一些自然邊界,比如日期的,建議利用日期進行分區。
<b>map join開啟</b>
我們可以啟用連接配接自動轉換來幫助我們轉換,在執行語句之前設定一下即可。它是經過優化的map join,無reducer。
<b>skew join</b>
真實資料中資料傾斜是一定的, hadoop 中預設是使用
也就是每個節點的reduce 預設是處理1g大小的資料,如果你的join 操作也産生了資料傾斜,那麼你可以在hive 中設定
hive 在運作的時候沒有辦法判斷哪個key 會産生多大的傾斜,是以使用這個參數控制傾斜的門檻值,如果超過這個值,新的值會發送給那些還沒有達到的reduce, 一般可以設定成你
(處理的總記錄數/reduce個數)的2-4倍都可以接受.
傾斜是經常會存在的,一般select 的層數超過2層,翻譯成執行計劃多于3個以上的mapreduce job 都很容易産生傾斜,建議每次運作比較複雜的sql 之前都可以設一下這個參數. 如果你不知道設定多少,可以就按官方預設的1個reduce 隻處理1g 的算法,那麼 skew_key_threshold = 1g/平均行長. 或者預設直接設成250000000 (差不多算平均行長4個位元組)
<b>sort-merge-bucket join</b>
如果表已經排序并且已經bucketed,可以啟用smb joins