名词解释:

名词解释:

order by

  Hive中的order by和数据库中的order by 功能一致,按照某一项或者几项排序输出,可以指定是升序或者是降序排序。它保证全局有序,但是进行order by的时候是将所有的数据全部发送到一个Reduce中,所以在大数据量的情况下可能不能接受,最后这个操作将会产生一个文件。

sort by

  sort by只能保证在同一个reduce中的数据可以按指定字段排序。使用sort by 你可以指定执行的reduce个数 (set mapreduce.job.reduce=) 这样可以输出更多的数据。对输出的数据再执行归并排序,即可以得到全部结果。需要注意的是,N个Reduce处理的数据范围是可以重叠的,所以最后排序完的N个文件之间数据范围是有重叠的。

distribute by

  按照指定的字段将数据划分到不同的输出reduce中。这个可以保证每个Reduce处理的数据范围不重叠,每个分区内的数据是没有排序的。

cluster By

  cluster by 除了具有 distribute by 的功能外还兼具 sort by 的功能。 所以最终的结果是每个Reduce处理的数据范围不重叠,而且每个Reduce内的数据是排序的,而且可以打到全局有序的结果。

 

原文地址:

 

根据一些具体SQL实例来介绍说明cluster by、distribute by + sort by和order by的区别。同时通过实例说明create table指定clustered by 和sort by。

create table table(c1 int,c2 int,c3 int);
 insert into table dual select 1,2,3 from (select count(*) from dual)a;
 insert into table dual select 1, 3, 4 from (select count(*) from dual)a;
 insert into table dual select 1, 1, 5 from (select count(*) from dual)a;
 insert into table dual select 1, 2, 2 from (select count(*) from dual)a;
 insert into table dual select 1, 1, 2 from (select count(*) from dual)a;
 hive> select * from dual;
 OK
 1   2   3
 1   3   4
 1   1   5
 1   2   2
 1   1   2
 Time taken: 0.105 seconds, Fetched: 5 row(s)create table t1_cluster (c1 int,c2 int,c3 int) clustered by (c2) sorted by (c3) into 2 buckets;
 insert overwrite table t1_cluster select * from dual;
 hive> select * from t1_cluster;
 OK
 1   2   2
 1   2   3
 1   1   2
 1   3   4
 1   1   5
 Time taken: 0.111 seconds, Fetched: 5 row(s)



上面的脚本主要是为了构建数据,其中dual表数据可以认为是源表数据,而t1_clsuter表数据则是clustered by c2 并且sort by c3,同时写入2个buckets。

cluster by
首先设置reduce个数为2,为了可以更加清晰地看到数据分布。

set mapred.reduce.tasks=2;
 hive> select * from t1_cluster cluster by c2;
 OK
 --bucket0
 1   2   3
 1   2   2
 --bucket1
 1   1   5
 1   1   2
 1   3   4
 Time taken: 1.768 seconds, Fetched: 5 row(s)


从结果里面可以看到,如果SQL指定cluster by c2,则数据基于c2分布,且按照升序排序。

distribute by

hive> select * from t1_cluster distribute by c2;
 OK
 --bucket0
 1   2   3
 1   2   2
 --bucket1
 1   1   5
 1   3   4
 1   1   2
 Time taken: 1.77 seconds, Fetched: 5 row(s)


从结果可以看到,数据是基于c2分布,但并没有按照c2升序或者降序排序。 
这里也清晰看到cluster by和distribute by的区别在于都是基于key分布,前者会按照key升序排序,而后者不会排序。

distribute by +sort by

hive> select * from t1_cluster distribute by c2 sort by c3;
 OK
 --bucket0
 1   2   2
 1   2   3
 --bucket1
 1   1   2
 1   3   4
 1   1   5
 Time taken: 1.69 seconds, Fetched: 5 row(s)


从结果可以清晰看到,数据基于c2分布,但同时基于c3升序排序。 
下面同时对比下sort by添加c2列。

hive> select * from t1_cluster distribute by c2 sort by c2,c3;
 OK
 --bucket0
 1   2   2
 1   2   3
 --bucket1
 1   1   2
 1   1   5
 1   3   4
 Time taken: 1.767 seconds, Fetched: 5 row(s)



从结果来看,与sort by c2不同的是,这条SQL返回的结果不仅基于c2分布,同时还是基于c2,c3有序。 这里再添加一个例子。

hive> select * from t1_cluster distribute by c2 sort by c2;
 OK
 --bucket0
 1   2   3
 1   2   2
 --bucket1
 1   1   5
 1   1   2
 1   3   4
 Time taken: 1.728 seconds, Fetched: 5 row(s)



这里主要是为了说明,cluster by c2与distribute by c2 sort by c2返回的结果其实是一致的,也即两者写法其实是等价。

order by

hive> select * from t1_cluster order by c2;
 OK
 1   1   5
 1   1   2
 1   2   3
 1   2   2
 1   3   4
 Time taken: 1.757 seconds, Fetched: 5 row(s)


查询语句order by c2结果是所有数据基于c2有序,也就是说order by是对整个数据集进行排序。

小结1
cluster by key是根据key对数据进行分布,并且在每个bucket里面根据key进行排序。而distribute by key仅仅是根据key对数据进行分布,如果同时添加sort 
by子句,则会保证每个bucket数据是根据sort by的key有序。同时如果distribute by和sort by的key是相同情况下,则等价于cluster by子句。即cluster by kes <==>distribute by keys sort by keys。而order by则是对整个数据进行排序,没有任何分布概念。

create table …clustered by key1 sort by key2
最开始表的创建SQL可以看到t1_cluster表创建其实是cluster by c2然后sort by c3。然后查看所有数据。

hive> select * from t1_cluster;
 OK
 --bucket0
 1   2   2
 1   2   3
 --bucket1
 1   1   2
 1   3   4
 1   1   5
 Time taken: 0.105 seconds, Fetched: 5 row(s)



首先t1_cluster创建了2个buckets,所以值2分布在bucket0号,而1分布在bucket1(取模)。发现对于bucket1的所有值,c2并没有排序,而对于c3列每个bucket都是基于c3有序。 
所以create table的clustered by其实仅仅是分布,与Select语句中的cluster by其实并不一样。而是和Select语句中的distribute by相同。所以create table的clustered by sorted by其实等价于select的distribute by sort by。