Hive SQL 常見問題(轉載)

http://www.aboutyun.com/thread-14942-1-1.html

問題導讀
一、Hive查詢語句和SQL查詢語句區別與聯繫。
二、distribute by、group by和Sort by的區別。
三、MapJoin的優缺點是什麼?



聚合函數
1.count計數
count(*):不全都是NULL,就加1;count(1):當只要有一列是NULL就不會加1;count(col):當col列不爲空就會加1
2.sum求和
sum(可轉成數字的值)返回bigint,好比求和後加1,1必須轉化成爲bigint類型,sum(col)+cast(1 as bigint)
3.avg求平均值
avg(可轉化成數字的值)返回double
4.distinct不一樣值的個數
count(distinct col)

Order by
按照某些字段排序,後面能夠有不少列進行排序,默認是字典排序。Order by 是全局排序,Order by這個過程只須要一個且只有一個reduce,不管你配置多少各reduce,到最後都會彙總一個reduce進行Order by,因此當數據量很是大的時候要考慮好是否使用Order by;
select c1,other from tableName where condition order by c1,c2[asc|desc]
如:select * from usertable order id asc,name desc;

Group by
根據某些字段值進行分組,有相同值的放到一塊兒。注意,select後面查詢的列,除了聚合函數外都應該出現再group by中,group by後面也能夠跟表達式,如substr(col),對某一列字段截取的部分進行分組。having是在group by以後進一步進行篩選的。他使用了reduce操做,受限於reduce個數,設置reduce參數mapred.reduce.tasks。文件的輸出個數就是reduce個數,文件大小與reduce處理的數據量相關。存在的問題:網絡負載太重;數據傾斜,優化參數hive.groupby,skeweindata設置爲true(起兩個mapreduce,第一個在每一個key加一個隨機值,而後進行group by)。

select c1,[c2..] count(1).. from test_group where condition group by c1[,c2..] [having]
set mapred.reduce.tasks=n;
set hive.groupby.skewindata=true;
select name,count(1) as num from tableName group by name;

group by 與distinct
都能達到去重的效果,走的mapreduce都是同樣的流程,其reduce個數優化,還有hive.groupby.skewindata都起做用。group by中查找的必須在group by 中出現,可是distinct能夠,可是distinct須要後面的多個col都相同纔會去重。

Join錶鏈接
兩個表m和n之間按照on條件進行鏈接,m中的一條記錄和n中的一條記錄組成一條新的記錄。
join:等值鏈接(內鏈接),只有m和n中同時存在纔會篩選出。
如:
tableA col1 col2
       1   w
       2   j
       4   g
tableB col3 col4
      1   y
      1   t
      5   z
select a.col1,a.col2,b.col4 from (select col1,col2 from tableA) a join (select col3,col4 from tableB) b on a.col1=b.col3
     result:
     1 w y
     1 w t
left outer join:左邊的表的值不管是否在右表中出現,都會做爲結果輸出,若是右邊的值不存在則爲NULL。而右邊表的值只有在左邊的值出現纔會出現。
select a.col1,a.col2,b.col4 from (select col1,col2 from tableA) a left outer join (select col3,col4 tableB) b on a.col1=b.col3
    result:
    1 w y
    1 w t
    2 j NULL
    4 g NULL
right outer join:與left outer join正相反
  result:
    1 w y
    1 j y
    5 NULL z
left semi join :相似exists,判斷左表中數據是否在右表中,若是在則篩選出來。
select a.col1,a.col2,b.col4 from (select col1,col2 from tableA) a left semi join (select col3,col4 from tableB) b on a.col1=b.col3
    result:
    1 w y
mapjoin:在map端完成join操做,不須要reduce,基於內存作join,屬於優化操做,可是須要將整個表加載到內存中去。

select m.col1 as col1,m.col2 as col2,n.col3 as col3
from 
(select col1,col2 from tableA where condition(在map端執行) )m
[left outer|right outer|left semi] join
(select col3 from tableB)n
on m.col1= n.col3 [and condition]
where condition(在reduce端執行)
注:hive中join不能使用相似<,>這種比較 
若是尋在數據傾斜問題能夠設置:
set hive.optimize.skewjoin=true;

MapJoin
在map端把小表加載到內存中,而後讀取大表,和內存中的小表進行比較。其中使用了分佈式緩存。
優缺點:
不消耗reduce資源(reduce相對較小);減小reduce操做,加快程序執行;下降網絡負載;
佔用部份內存,因此加載到內存中的表不能太大,由於每一個計算節點都會加載一次。生成較多小文件。(每一個map對應一個輸出文件)
使用MapJoin:
自動使用
配置:set hive.auto.convert.join=true;
set hive.mapjoin.smalltable.filesize=n(當查詢的表中小表小於等於這個值就會使用MapJoin。可是可能會有不少任務,都加載進去了消耗內存)
手動指定
slelet /*+mapjoin(n)*/ m.col1,m.col2,n.col4 from (...)m join (...)n on m.col1=n.col3
也就是在select中將小表使用/*+mapjoin(n)*/參數加載到內存中去

Distribute by 和 Sort by
distribute by col1,col2
按照col列將數據分散到不一樣的reduce
sort by col1,col2[asc|desc]
將col1,col2列排序(這是將每一個reduce內部排序)
二者接合使用,確保每一個reduce的輸出都是有序的,可是總體不是有序的。

distribute by 和 group by
都是按照key劃分數據
都是用reduce操做
distribute by只是單純的分散數據,而group by是將相同的key彙集到一塊兒,後續必須是聚合操做
order by 和sort by
order by確保全局有序
sort by只是保證每一個reduce上面輸出有序,若是隻有一個reduce時,和order by效果同樣
應用場景
小文件過多(經過reduce個數來控制輸出文件個數)
文件超大
map輸出的文件大小不均
reduce輸出的文件大小不均

cluster by 
把有相同的數據彙集到一塊兒,並排序
cluster by col
至關於:distribute by col col order by col

union all
將多個表的數據合併成一個表,hive部支持union操做
select col 
from(
select a as col from t1
union all
select b as col from t2
)tmp
沒有reduce操做
要求:
字段名字同樣(能夠經過as使用別名)
字段類型同樣
字段個數同樣(子查詢的個數)
字表不能又別名(join每一個子查詢要別名)
合併以後的表若是須要查詢數據,則須要給合併結果起別名
相關文章
相關標籤/搜索