Hive 区分cluster by、distribute by + sort by、order by以及创建表带有clustered by和sort by

Hive 区分cluster by、distribute by + sort by、order by以及创建表带有clustered by和sort by

本文主要根据一些具体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。

你可能感兴趣的:(Hive)