1. 程式人生 > >Hive的排序以及分桶抽樣查詢

Hive的排序以及分桶抽樣查詢

排序

全域性排序(Order by) :一個MapReduce

使用order by子句查詢

ASC(ascend):升序(預設)
DESC(descend):降序

Order by子句在Select語句結尾

查詢員工資訊按工資升序排列

 select * from emp order by sal;

查詢員工資訊按工資降序排列

	 select * from emp order by sal desc;

按照別名排序

按照員工薪水的 2 倍排序

hive (hive)> select ename,sal*2 twosal from emp order by twosal;

多個列排序

按照部門和工資升序排序

hive (hive)> select ename,deptno,sal from emp order by deptno,sal;

每個MapReduce內部排序(Sort By)

Sort By:每個MapReduce內部進行排序,對全域性結果集來說不是排序

1)設定 reduce 個數

set mapreduce.job.reduces=3;

2)檢視設定 reduce 個數

set mapreduce.job.reduces;

3)根據部門編號降序檢視員工資訊

select * from emp sort by empno desc;

4)將查詢結果匯入到檔案中(按照部門編號降序排序)

分割槽排序(Distribute By)

Distribute By : 類似MR中partition,進行分割槽,結合Sort by使用

注意:Hive要求distribute by 語句要寫在sort by語句之前
對於 distribute by 進行測試,一定要分配多 reduce 進行處理,否則無法看到 distribute by
的效果

(1)先按照部門編號分割槽,再按照員工編號降序排序。

hive (default)> set mapreduce.job.reduces=3;
hive (default)> insert overwrite local directory '/opt/module/datas/distribute-result' select *
from emp distribute by deptno sort by empno desc;

Cluster By

當 distribute by 和 sorts by 欄位相同時,可以使用 cluster by 方式

cluster by 除了具有 distribute by 的功能外還兼具 sort by 的功能。但是排序只能是倒序排序,不能指定排序規則為 ASC 或者 DESC。

select * from emp cluster by deptno;

等價於

select * from emp distribute by deptno sort by deptno;

分桶以及抽樣查詢

分桶表資料儲存

分桶和分割槽的區別

分割槽針對的資料儲存路徑,分桶針對的是資料檔案
分割槽提供一個隔離資料和優化查詢的便利方式,不過並非所有的資料集都可以形成合理的分割槽,特別是確定合適的劃分大小疑慮
分桶是將資料集分解成更容易管理的若干部分的另一個技術

原始資料

1001 ss1
1002 ss2
1003 ss3
1004 ss4
1005 ss5
1006 ss6
1007 ss7
1008 ss8
1009 ss9
1010 ss10
1011 ss11
1012 ss12
1013 ss13
1014 ss14
1015 ss15
1016 ss16

建立分桶表

create table stu_buck(id int,name string)
clustered by(id)
into 4 buckets
row format delimited fields terminated by '\t';

查看錶的詳細結構

hive (hive)> desc formatted stu_buck;
...
Num Buckets:        	4  

載入資料

hive (hive)> load data local inpath '/opt/datas/student.txt' into table stu_buck;

在這裡插入圖片描述
並沒有將檔案分開

因為沒有設定引數

2)建立分桶表時,資料通過子查詢的方式匯入

(1)先建一個普通的 stu 表

hive (hive)> create table stu(id int,name string) row format delimited fields terminated by '\t';

(2)向普通的 stu 表中匯入資料

hive (hive)> load data local inpath '/opt/datas/student.txt' into table stu;

(3)清空 stu_buck 表中資料

hive (hive)> truncate table stu_buck;

(4)設定屬性開啟分桶

hive (hive)> set hive.enforce.bucketing=true;
hive (hive)> set mapreduce.job.reduces=-1;

(5)重寫寫入資料

hive (hive)> insert into table stu_buck select id,name from stu cluster by (id);

在這裡插入圖片描述
這裡可以看出分割槽是對於資料夾的操作,分桶是對檔案的操作

分桶抽樣查詢

對於非常大的資料集,有時使用者需要使用的是一個具有代表性的查詢結果而不是全部結
果。Hive 可以通過對錶進行抽樣來滿足這個需求

查詢stu_buck中的資料

hive (hive)> select * from stu_buck tablesample(bucket 1 out of 4 on id);
OK
stu_buck.id	stu_buck.name
1004	ss4
1008	ss8
1012	ss12
1016	ss16
Time taken: 0.169 seconds, Fetched: 4 row(s)

tablesample是抽樣語句,語法:tablesample(bucket x out of y)

y必須是table總bucket數的倍數或者因子,hive根據y的大小,決定抽樣比例
table總共分成4份,當y=2時,抽取(4/2)=2個bucket的資料,當y=8時,抽取(4/8=)1/2個bucket的資料
x 表示從哪個 bucket 開始抽取。例如,table 總 bucket 數為 4,tablesample(bucket 4 out of4),表示總共抽取(4/4=)1 個 bucket 的資料,抽取第 4 個 bucket 的資料
注意:x必須小於y
否則

FAILED: SemanticException [Error 10061]: Numerator should not be bigger than
denominator in sample clause for table stu_buck

資料塊抽樣

Hive 提供了另外一種按照百分比進行抽樣的方式,這種是基於行數的,按照輸入路徑
下的資料塊百分比進行的抽樣。

hive (hive)> select * from stu tablesample(0.1 percent);

提示:這種抽樣方式不一定適用於所有的檔案格式。另外,這種抽樣的最小抽樣單元是
一個 HDFS 資料塊。因此,如果表的資料大小小於普通的塊大小 128M 的話,那麼將會返回
所有行。