Hive學習之動態分區及HQL


Hive動態分區

1、首先創建一個分區表
create table t10(name string)
partitioned by(dt string,value string)
row format delimited fields terminated
by '\t' lines terminated by '\n'
stored as textfile;
2、然后對hive進行設置,使之支持動態分區,
set hive.exec.dynamic.partition.mode=nonstrict;
如果限制是strict,則必須有一個靜態分區,且放在最前面
set hive.exec.dynamic.partition.mode=strict;
3、最后向t10表中插入數據,同時指定分區
insert overwrite table t10 partition(dt='2014010090',value)
select '34' as name,addr as value from t9;
HQL函數
1、order by
    按照某些字段進行排序,例如:select clol,clo2... from table_name where condition order by clo1,clo2[asc|desc];order by 后面可以對多列進行排序,默認按照字典進行排序,order by為全局排序,它需要reduce操作,並且只有一個reduce,和配置沒有關系
假如表t2中的數據格式為:

id     name
1    zhangsan
2      lisi
3     wangwu
4     sunfei
5     cuiying
對此進行語句:select * from t2 order by id desc,name asc;
對第一列進行降序排列,對第二列進行升序排列。由於order by是全局排序,並且只使用了一個reduce,所以在實際應用中應該盡量少使用order by進行排序


2、group by
    按照某些字段的值進行分組,將相同的值放在一起
select col1[,col2],count(),sel_expr(聚合操作)
from table
where condition
group by col1[,col2]
[having]
注意,select后面非聚合列必須出現在group by中,除了普通列就是一些聚合操作,group by后面也可以跟表達式,比如substr(col)
同時,group by 使用了reduce操作,受限於reduce的數量,設置reduce的數量可以mapred.reduce.tasks,輸出文件個數和reduce的個數
相同,文件大小與reduce處理的數據量有關,在實際應用過程中,它存在一些問題,如網絡負載過重以及數據傾斜(在處理數據過程中,從map到reduce的過程是按照key值進行划分,
由key值決定文件是由哪個reduce來執行,假如某一個reduce中處理的key過多,即就是某一個reduce處理任務過多,執行時間過長,導致整個Job作業執行時間過長,在其他reduce任務已經完成后,
這個處理過多reduce的任務會嚴重拖慢整體任務的完成時間,這就是數據傾斜,可以通過將
hive.groupby.skewindata參數設置為true,hive自動啟動優化程序來避免數據傾斜)等問題。
例如:set mapred.reduce.tasks=5;
      set hive.groupby.skewindata=true;//數據傾斜時候可以使用
      select country,count(1) as num from info group by country;


3、join
兩個表m,n之間按照On條件進行連接,m中的一條記錄和n中的一條記錄組成一條新紀錄,它是等值連接,只有某個值在m和n中同時存在的時候才可以進行連接操作,left outer join 左邊外接,左邊
表中的值無論是否在b中存在的時候,都輸出,右邊表中的值只有在左邊表中存在的時候才輸出,left outer join則相反,left semi join的作用類似於exits, mapjoin則是在map端完成join操作,
不需要reduce,基於內存做join,屬於優化操作
例如:
a表:     b表:
co1 co2   co3   co4
1    w     1     f
3    e     1     g
5    r     4     j
對a和b表執行語句:
select s.co1,s.co2,t.co4
from
(select col from a where ...(map端執行))s(左表)
join
(select col from b)t(右表)
on s.co1 = t.co3
where condition(reduce端執行)
其結果為:
1 w f
1 w g
5 e j
執行過程是:對於a表中的每一行數據,在b表中進行遍歷,如果查找到相同的則提取這一樣存在一個新表中。
如果將join修改為:left outer join 則執行結果為:
1 w f
1 w g
5 e j
3 r null
執行原則是:key值必須在a表中存在,但可以不在b表中存在
如果將join修改為:right outer join 則執行結果為:
1 w f
1 w g
5 e j
2 null p
執行原則是:key值必須在b表中存在,但可以不在a表中存在
如果將join修改為:left semi join 則執行結果為:
1 w f
5 e j
執行原則是:首先查看a表中的第一條記錄,如果在b中存在相同記錄則輸出a中的記錄


4、Mapjoin
    Mapjoin在map端把小表加載到內存中,然后讀取大表,和內存中的小表完成連接操作,
其中使用了分布緩存技術,它的執行不消耗集群的reduce資源(因為集群的reduce
資源相對短缺),減少了reduce操作,加快程序執行,降低網絡負載,但是,它占用
部分內存,所以加載到內存中的表不能過大,因為每個計算節點都會加載一次,同時
會生成較多的小文件。
    通過如下配置,hive自動根據sql選擇使用common join或者map join
    set hive.auto.convert.join=true;
    hive.mapjoin.smalltable.filesize默認值為25Mb
還可以手動指定:
    select/*+mapjoin(n(表名))*/m.col,m.col2,n.col3 from m
    join n
    on m.col = n.col
總之,mapjoin的使用場景主要有:
    關聯操作中有一張表非常小,大表和小表進行關聯
    不等值的鏈接操作


5、Hive分桶
    (1)對於每一個表或者分區,Hive可以進一步組織成桶,也就是說桶是更為細粒度的數據
    范圍划分
    (2)Hive是針對某一列進行分桶
    (3)Hive采用對列值哈希,然后除以桶的個數求余的方式決定該條記錄存放在哪個桶中
    分桶的好處是可以獲得更高的查詢處理效率,使取樣更高效
    create table t(id int,name string)
    clustered by(id)sorted by(name)into 4 buckets
    row format delimited fields terminated by '\t'
    stored as textfile;
    set hive.enforce.bucketing=true;
6、分桶的使用
    select * from t tablesample(bucket 1 out of 2 on id)
    這句話的意思是將所有的桶分成兩份,然后取其中的一份
    bucket join
    set hive.optimize.bucketmapjoin = true;
    set hive.optimize.bucketmapjoin.sortedmerge =true;
    set hive.input.format = org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
    連接兩個在(包含連接列)相同列張划分了桶的表,可以使用Map端連接(Map-site join)
    高效的實現,比如Join操作。對於Join操作兩個表有一個相同的列,如果對這兩個表都進
    桶操作,那么將保存相同列值得桶進行Join操作就可以,可以大大減少Join的數據量
    對於Mapd端連接的情況,兩個表以相同方式划分桶。處理左邊表某個桶的mapper知道右邊表
    內相匹配的行在對應的桶內。因此,mapper只需要獲取那個桶(這只是右邊表內存儲數據的
    一小部分)即可進行連接。這一優化方法並不一定要求兩個表的桶的個數相同,兩個表的桶
    個數是倍數關系也可以。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM