Hive排序关键字区别详解

Hive中主要有四个用于排序的关键字,它们各有特点,适用于不同的场景。

核心区别总结如下表,之后会进行详细解释:

特性ORDER BYSORT BYDISTRIBUTE BYCLUSTER BY
全局/局部排序全局排序局部排序(Reducer内)仅分区,不排序局部排序(分区内且排序)
Reducer数量1个多个多个多个
输出文件数1个多个多个多个
功能描述对所有数据进行整体排序,保证全局有序在每个Reducer内部进行排序按照指定字段分区,控制数据分发DISTRIBUTE BY + SORT BY 的简写
性能(数据倾斜和单点压力风险)-
使用场景需要最终全局有序结果的场景大规模数据并行排序,不要求全局有序为后续的聚合或排序做数据分区准备既想分区,又希望分区内有序

详细说明与区别

1. ORDER BY
  • 功能全局排序。它会将所有数据汇集到一个Reducer中进行排序,最终保证输出文件中的数据是全局有序的。
  • 特点
    • 因为只有一个Reducer处理所有数据,所以当数据量非常大时,容易成为性能瓶颈,运行速度很慢。
    • 可能会因为数据量过大而导致Reducer内存溢出(OOM)。
  • 使用场景:当数据量不大,或者你必须要一个完全有序的最终结果时(例如,查询排行榜Top 10)。
  • 示例
    -- 查询员工工资并从高到低全局排序
    SELECT name, salary
    FROM employee
    ORDER BY salary DESC;
    -- 结果只有一个文件,里面所有数据按salary降序排列
    
2. SORT BY
  • 功能局部排序。它在每个Reducer内部对数据进行排序。也就是说,每个Reducer输出的文件自身是有序的,但多个Reducer输出的文件之间是无序的。
  • 特点
    • 在多个Reducer上并行执行,性能远高于ORDER BY
    • 排序的范围受DISTRIBUTE BY的影响。如果没用DISTRIBUTE BY,Hive会随机分发数据到Reducer。
  • 使用场景:处理大规模数据集,且不要求全局结果有序,只要求每个输出文件有序(例如,为后续的归并排序做准备)。
  • 示例
    -- 设置Reducer数量为2
    SET mapreduce.job.reduces = 2;
    
    -- 每个Reducer会处理一部分数据,并在内部按salary排序
    SELECT name, salary
    FROM employee
    SORT BY salary DESC;
    -- 结果可能有两个文件:
    -- File1: (Alice, 100), (Bob, 90)   -> 有序
    -- File2: (David, 120), (Cathy, 110) -> 有序
    -- 但File2的第一行工资(120)比File1的最后一行(100)高,所以全局是无序的。
    
3. DISTRIBUTE BY
  • 功能控制分区。它负责将Map端输出的数据,按照指定的字段分发到不同的Reducer中。它不保证每个Reducer内部的数据是否排序。
  • 特点
    • 类似于MapReduce中的Partitioner,决定了数据由哪个Reducer处理。
    • 通常与SORT BY结合使用,实现“先按字段A分区,再在分区内按字段B排序”。
  • 使用场景:当需要将相同key的记录发送到同一个Reducer进行处理时(例如,根据部门ID分区,然后对每个部门的员工进行排序)。
  • 示例
    SET mapreduce.job.reduces = 2;
    
    -- 根据部门id分发数据到Reducer,然后在每个Reducer内按工资排序
    SELECT name, dept_id, salary
    FROM employee
    DISTRIBUTE BY dept_id
    SORT BY salary DESC;
    -- 相同dept_id的员工会被分配到同一个Reducer
    -- 然后在每个Reducer内部,这些员工再按工资降序排列
    
4. CLUSTER BY
  • 功能分区并排序。它是DISTRIBUTE BYSORT BY简写形式。当DISTRIBUTE BY的字段和SORT BY的字段相同时,就可以直接用CLUSTER BY替代。
  • 特点
    • CLUSTER BY col 等价于 DISTRIBUTE BY col SORT BY col
    • 它既负责按字段分区,又负责在分区内按同一个字段排序。注意:排序只能是升序(ASC),不能指定降序(DESC)。
  • 使用场景:分区和排序的字段是同一个,且只需要默认升序时。
  • 示例
    -- 以下两条语句是等价的
    SELECT name, dept_id
    FROM employee
    CLUSTER BY dept_id;
    
    SELECT name, dept_id
    FROM employee
    DISTRIBUTE BY dept_id
    SORT BY dept_id; -- CLUSTER BY 默认是升序
    

总结与选择建议

  1. 要全局有序 -> 用 ORDER BY(数据量小的时候)。
  2. 要局部有序,且分区和排序字段不同 -> 用 DISTRIBUTE BY ... SORT BY ...
  3. 要局部有序,且分区和排序字段相同 -> 用 CLUSTER BY(注意只能是升序)。
  4. 只需要局部有序,不关心如何分区 -> 用 SORT BY(让Hive随机分区)。

理解这些区别的关键在于深入理解Hive和MapReduce的工作原理:数据如何从Map端发出,如何通过Partitioner分发到不同的Reducer,以及最终如何输出。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值