hive中order by,sort by,distribute by,cluster by作用和用法
数据准备
1 | -- zxz_5.name | zxz_5.nid | zxz_5.phone | zxz_5.ntime | zxz_5.year | zxz_5.month |
order by
hive中的order by 语句和其他的sql方言中定义是一样的,其会对查询结果集执行一个全局排序,这也就是说会有一个所有的数据都通过一个reduce进行处理的过程,对于大数据集,这个过程将消耗很大的时间来执行。
1 | select * from zxz_5 order by nid desc,year(ntime); |
sort by
hive增加了一个可供选择的方式,也就是sort by ,其实会在每个reduce中对数据进行排序,也就是执行一个局部排序过程。这可以保证每个reduce的输出数据都是有序的(但并非全局有效)。这样就可以提高后面进行的全局排序的效率了。对于这两种情况,语法区别仅仅是,一个关键字是order,另一个关键字是sort。用户可以指定任意期望进行排序的字段,并可以在字段后面加上asc关键字(默认)表示升序,desc关键字是降序排序
1 | -- 在sort by之前我们还有配置属性: |
sort by 和 distribute by
distribute by 控制 map的输出在reduer中是如何划分的,mapreduce job 中传输的所有数据都是按照键-值对的方式进行组织的,
因此hive在将用户的查询语句转换成mapreduce job时,其必须在内部使用这个功能。
默认情况下,MapReduce计算框架会依据map输入的键计算相应的哈希值,然后按照得到的哈希值将键-值对均匀分发到多个reducer中去,
不过不幸的是,这也是意味着当我们使用sort by 时,不同reducer的输出内容会有明显的重叠,至少对于排序顺序而已只这样,
即使每个reducer的输出的数据都有序的。如果我们想让同一年的数据一起处理,那么就可以使用distribute by 来保证具有相同年份的数据分发到同一个reducer中进行处理,
然后使用sort by 来安装我们的期望对数据进行排序:
Distribute by 和 group by 在其控制着reducer是如何接受一行行数据进行处理这方面类似的,而sort by 则控制着reducer内的数据是如何进行排序的,需要注意的是,hive需求distribute by 语句写在sort by 语句前
1 | set mapreduce.job.reduces=2; |
cluster by
在之前列子中,year(ntime)用在distribute by 语句中,而nid列位于sort by语句中,如果这两个语句涉及到列的完全相同,而且采用的是升序的方式,那么就可以用到cluster by ,他等价于 distribute by 和sort by 是一个简写方式
1 | select * from zxz_5 z cluster by z.nid ; |