hive教程:对查询结果进行排序(distribute by)

介绍

并没有排序的功能

distribute by 会根据指定 字段的值,将记录 分发到不同的 reduce 中

分区规则

默认是对指定列的值取 hash 值,然后hash值对reduce的个数取模,余数相同的分到一个区。也就意味着 同一个分区 中的 字段不一定相同。

相当于调用 MapReduce 的 HashPartitioner

注意: reduce 的数量要大于1,才能体现出来

与 sort by 关系

每个reduce中的数据并 不是有序的。因此,distribute by 经常和 sort by 配合使用。Hive 要求 distribute by 语句要写在 sort by 语句之前

一句话解释

distribute by 根据列的值,将数据分给不同的 reduce,最终保存到文件中

与 sort by 区别

sort by 不是根据后面的列值进行分发 reduce

语法

select * from 表名 distribute by 列名 sort by 列名 [asc/desc];

例

emp 表中的记录有3类 deptno,设置3个 reducer:

set mapreduce.job.reduces=3;

查看 reducer数量:

set mapreduce.job.reduces;

执行下面sql:

insert overwrite local directory '/program/result_dist/'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
select ename,deptno,sal from emp distribute by deptno ;

执行结果:

有 3 类deptno,那么设置 3 个reducer,每类 deptno 分给一个reducer,每个 reducer 生成 1 个文件

最终每一类 deptno,保存在 一个文件中

每个文件中的数据不会做排序

原理

对部门编号 10、20、30 封装成 IntWritable,再算 hash,然后对 2 取模,观察执行结果:

public static void main(String[] args) {
    IntWritable t = new IntWritable(10);
    IntWritable t2 = new IntWritable(20);
    IntWritable t3 = new IntWritable(30);

    System.out.println( t.hashCode()%3 + "-"+t.hashCode());
    System.out.println( t2.hashCode()%3 + "-"+t2.hashCode());
    System.out.println( t3.hashCode()%3 + "-"+t3.hashCode());
}

结果如下:

1-10
2-20
0-30

结论:

  • 说明 0号文件 是部门编号 10 的数据
  • 说明 1号文件 是部门编号 20 的数据
  • 说明 3号文件 是部门编号 30 的数据

reduce 数量是 2

如果 reducer 数量不是3,是2,那么分类的策略会不同,有1个文件是空的,没有数据

原理

对部门编号 10、20、30 封装成 IntWritable,再算 hash,然后对 2 取模,观察执行结果:

public static void main(String[] args) {
    IntWritable t = new IntWritable(10);
    IntWritable t2 = new IntWritable(20);
    IntWritable t3 = new IntWritable(30);

    System.out.println( t.hashCode()%2 + "-"+t.hashCode());
    System.out.println( t2.hashCode()%2 + "-"+t2.hashCode());
    System.out.println( t3.hashCode()%2 + "-"+t3.hashCode());
}

结果如下:

0-10
0-20
0-30

结论:说明 0号文件有数据,1号文件是空的

感谢:
https://blog.csdn.net/u012369535/article/details/89639434


原文出处:/show_1IXmZ7GsEaN.html