Hive的四种排序方法
hive排序方法,hive的排序方式
hive有四种排序方法: ORDER BY 、SORT BY 、DISTRIBUTE BY 、CLUSTER BY
0. 测试数据准备
--数据准备
WITH t_emp_info AS (
SELECT * FROM (
VALUES (1001, '研发部', 16000 )
, (1002, '市场部', 17000 )
, (1003, '销售部', 11000 )
, (1004, '研发部', 15000 )
, (1005, '销售部', 12000 )
, (1006, '研发部', 21000 )
, (1007, '产品部', 16000 )
, (1008, '研发部', 18000 )
, (1009, '市场部', 17000 )
, (1010, '产品部', 16000 )
, (1011, '销售部', 10000 )
, (1012, '研发部', 18000 )
, (1013, '市场部', 15000 )
) AS table_name(uuid, dept, salary)
)
uuid | dept | salary |
---|
1001 | 研发部 | 16000 |
1002 | 市场部 | 17000 |
1003 | 销售部 | 11000 |
1004 | 研发部 | 15000 |
1005 | 销售部 | 12000 |
1006 | 研发部 | 21000 |
1007 | 产品部 | 16000 |
1008 | 研发部 | 18000 |
1009 | 市场部 | 17000 |
1010 | 产品部 | 16000 |
1011 | 销售部 | 10000 |
1012 | 研发部 | 18000 |
1013 | 市场部 | 15000 |
1. ORDER BY(全局排序)
order by: 全局排序, 所有的任务分配在一个reduce上面, 可以保证全局有序, 当输入规模较大时, 将会花费大量的时间进行计算;
order by 后面可以有多列进行排序, 默认按照字典排序(asc(默认):升序, desc:降序);
如果指定 hive.mapred.mode=strict(严格模式, 默认是: nonstrict(非严格模式)), 严格模式下必须使用limit来限制输出条数,否则会报错;
-- order by 多列默认升序排列
SELECT
uuid, dept, salary
FROM t_emp_info a
ORDER BY dept, salary
;
uuid | dept | salary |
---|
1007 | 产品部 | 16000 |
1010 | 产品部 | 16000 |
1013 | 市场部 | 15000 |
1009 | 市场部 | 17000 |
1002 | 市场部 | 17000 |
1004 | 研发部 | 15000 |
1001 | 研发部 | 16000 |
1008 | 研发部 | 18000 |
1012 | 研发部 | 18000 |
1006 | 研发部 | 21000 |
1011 | 销售部 | 10000 |
1003 | 销售部 | 11000 |
1005 | 销售部 | 12000 |
-- order by 降序排列
SELECT
uuid, dept, salary
FROM t_emp_info a
ORDER BY salary DESC
;
uuid | dept | salary |
---|
1006 | 研发部 | 21000 |
1012 | 研发部 | 18000 |
1008 | 研发部 | 18000 |
1002 | 市场部 | 17000 |
1009 | 市场部 | 17000 |
1001 | 研发部 | 16000 |
1007 | 产品部 | 16000 |
1010 | 产品部 | 16000 |
1004 | 研发部 | 15000 |
1013 | 市场部 | 15000 |
1005 | 销售部 | 12000 |
1003 | 销售部 | 11000 |
1011 | 销售部 | 10000 |
2. SORT BY (分区内排序)
sort by 是在进入 reducer之前进行排序, 也就是说保证了局部有序, 每一个reducer出来的数据是有序的, 但是不能保证全局的数据是有序的, 除非只有一个reducer存在;
sort by 出来的数据是局部有序, 在进行一次归并排序, 即可做到全局排序了, 可以提高全局排序的效率;
-- sort by 局部有序, 数据量少,没有体现局部有序的现象
SELECT
uuid, dept, salary
FROM t_emp_info a
SORT BY salary
;
uuid | dept | salary |
---|
1011 | 销售部 | 10000 |
1003 | 销售部 | 11000 |
1005 | 销售部 | 12000 |
1013 | 市场部 | 15000 |
1004 | 研发部 | 15000 |
1007 | 产品部 | 16000 |
1001 | 研发部 | 16000 |
1010 | 产品部 | 16000 |
1009 | 市场部 | 17000 |
1002 | 市场部 | 17000 |
1012 | 研发部 | 18000 |
1008 | 研发部 | 18000 |
1006 | 研发部 | 21000 |
3. DISTRIBUTE BY (分区)
distribute by 是控制map端输出结果分发, 相同字段的输出分发到一个reduce节点处理;
distribute by 一般和 sort by 一起使用, sort by 是将每一个reduce产生一个有序文件, 注意distribute by 要在 sort by 之前;
-- distribute by
SELECT
uuid, dept, salary
FROM t_emp_info a
DISTRIBUTE BY salary SORT BY salary DESC
;
uuid | dept | salary |
---|
1006 | 研发部 | 21000 |
1012 | 研发部 | 18000 |
1008 | 研发部 | 18000 |
1002 | 市场部 | 17000 |
1009 | 市场部 | 17000 |
1001 | 研发部 | 16000 |
1007 | 产品部 | 16000 |
1010 | 产品部 | 16000 |
1004 | 研发部 | 15000 |
1013 | 市场部 | 15000 |
1005 | 销售部 | 12000 |
1003 | 销售部 | 11000 |
1011 | 销售部 | 10000 |
4. CLUSTER BY (分区排序)
cluster by 具有 distribute by 和 sort by 的功能, 两者排序所用的列值相同时, 可以使用 cluster by 代替;
cluster by 只能使用升序, 不能使用降序, 不需要指定排序方式(ASC/DESC);
-- cluster by
SELECT
uuid, dept, salary
FROM t_emp_info a
CLUSTER BY salary
;
-- 两者结果一样
SELECT
uuid, dept, salary
FROM t_emp_info a
DISTRIBUTE BY salary SORT BY salary
;
uuid | dept | salary |
---|
1011 | 销售部 | 10000 |
1003 | 销售部 | 11000 |
1005 | 销售部 | 12000 |
1013 | 市场部 | 15000 |
1004 | 研发部 | 15000 |
1007 | 产品部 | 16000 |
1001 | 研发部 | 16000 |
1010 | 产品部 | 16000 |
1009 | 市场部 | 17000 |
1002 | 市场部 | 17000 |
1012 | 研发部 | 18000 |
1008 | 研发部 | 18000 |
1006 | 研发部 | 21000 |
end