Hive 中 Order By、Sort By、Cluster By 和 Distribute By 的详细解析

Hive 中 Order By、Sort By、Cluster By 和 Distribute By 的详细解析

在 Hive 数据查询与处理操作中,Order BySort ByCluster ByDistribute By 这些语句对于数据的排序、分区以及在 Reduce 阶段的处理起着关键作用。本文将详细解析它们各自的语法、区别以及一些使用要点,帮助大家深入理解并正确运用这些功能。

一、Order By 语法

Hive QL 中的 ORDER BY 语法与 SQL 语言中的 ORDER BY 语法相似。

(一)语法组成

sql 复制代码
colOrder: ( ASC | DESC )
colNullOrder: (NULLS FIRST | NULLS LAST)           -- (注意:在 Hive 2.1.0 及之后版本可用)
orderBy: ORDER BY colName colOrder? colNullOrder? (',' colName colOrder? colNullOrder?)*
query: SELECT expression (',' expression)* FROM src orderBy

(二)使用限制与注意事项

  1. 在严格模式(即 hive.mapred.mode=strict)下,ORDER BY 子句后面必须跟 LIMIT 子句;若将 hive.mapred.mode 设置为非严格模式,则不需要 LIMIT 子句。这是因为要对所有结果施加全局排序,就需要一个 Reducer 来对最终输出进行排序,如果输出的行数过多,单个 Reducer 可能会花费很长时间来完成排序工作。
  2. 通常是按列名指定列进行排序,不过在 Hive 0.11.0 及之后版本,若进行如下配置,则可以按位置指定列:
    • 对于 Hive 0.11.0 到 2.1.x 版本,设置 hive.groupby.orderby.position.aliastrue(默认值为 false)。
    • 对于 Hive 2.2.0 及之后版本,hive.orderby.position.alias 默认值为 true
  3. 默认的排序顺序是升序(ASC)。在 Hive 2.1.0 及之后版本,支持为 ORDER BY 子句中的每个列指定空值排序顺序,升序(ASC)时默认空值排序顺序为 NULLS FIRST,降序(DESC)时默认空值排序顺序为 NULLS LAST
  4. 在 Hive 3.0.0 及之后版本,子查询和视图中不带 LIMITORDER BY 语句会被优化器移除,若要禁用此功能,可设置 hive.remove.orderby.in.subqueryfalse

二、Sort By 语法

SORT BY 语法同样与 SQL 语言中的 ORDER BY 语法类似,其语法如下:

sql 复制代码
colOrder: ( ASC | DESC )
sortBy: SORT BY colName colOrder? (',' colName colOrder?)*
query: SELECT expression (',' expression)* FROM src sortBy

Hive 会依据 SORT BY 中指定的列在将数据行发送给 Reducer 之前对其进行排序,排序顺序取决于列的数据类型。如果列是数值类型,则按数值顺序排序;若是字符串类型,则按字典序排序。另外,在 Hive 3.0.0 及之后版本,子查询和视图中不带 LIMITSORT BY 语句会被优化器移除,同样可通过设置 hive.remove.orderby.in.subqueryfalse 来禁用此移除操作。

三、Sort By 和 Order By 的区别

Hive 支持 SORT BY 对每个 Reducer 内的数据进行排序,而 ORDER BYSORT BY 的区别在于:前者保证输出结果的全局有序性,后者仅保证在每个 Reducer 内数据行的有序性。如果存在多个 Reducer,使用 SORT BY 可能会得到部分有序的最终结果。

需要注意的是,单独的单列 SORT BYCLUSTER BY 之间的区别可能容易混淆。区别在于 CLUSTER BY 是依据字段进行分区,而 SORT BY 在有多个 Reducer 时会随机分区以便在各个 Reducer 间均匀分配数据(和负载)。例如:

sql 复制代码
SELECT key, value FROM src SORT BY key ASC, value DESC

假设有 2 个 Reducer,每个 Reducer 的输出可能是如下这样部分有序的情况:

复制代码
0   5
0   3
3   6
9   1
0   4
0   3
1   1
2   5

四、Sort By 的类型设置

在进行数据转换后,变量类型通常会被视为字符串,这意味着数值数据将按字典序排序。为解决这个问题,可以在使用 SORT BY 之前使用带有类型转换(cast)的第二个 SELECT 语句,示例如下:

sql 复制代码
FROM (FROM (FROM src
            SELECT TRANSFORM(value)
            USING 'mapper'
            AS value, count) mapped
      SELECT cast(value as double) AS value, cast(count as int) AS count
      SORT BY value, count) sorted
SELECT TRANSFORM(value, count)
USING 'reducer'
AS whatever

五、Cluster By 和 Distribute By 语法

Cluster ByDistribute By 主要在转换/Map - Reduce 脚本中使用,但在某些情况下,如果需要对查询输出进行分区和排序以供后续查询使用,在 SELECT 语句中也很有用。

(一)Cluster By

Cluster ByDistribute BySORT BY 的快捷方式,它会根据指定列同时进行数据的分区和排序操作。

(二)Distribute By

Hive 使用 Distribute By 中的列将数据行分配到各个 Reducer 中,所有具有相同 Distribute By 列值的行都会被分配到同一个 Reducer,但 Distribute By 并不保证对分配的键具有聚类或排序属性。例如,对以下 5 行数据基于 x 进行 Distribute By 分配到 2 个 Reducer 中:

复制代码
x1
x2
x4
x3
x1

则可能出现如下分配情况:

Reducer 1 得到:

复制代码
x1
x2
x1

Reducer 2 得到:

复制代码
x4
x3

可以看到,虽然能保证相同键 x1 的行被分配到同一个 Reducer(此处为 Reducer 1),但并不能保证它们在 Reducer 内是相邻聚集的。

而如果使用 Cluster By x,两个 Reducer 会进一步依据 x 对行进行排序,例如:

Reducer 1 得到:

复制代码
x1
x1
x2

Reducer 2 得到:

复制代码
x3
x4

用户也可以分别指定 Distribute BySORT BY,此时分区列和排序列可以不同,通常情况下分区列是排序列的前缀,但这并非强制要求,示例如下:

sql 复制代码
SELECT col1, col2 FROM t1 CLUSTER BY col1
SELECT col1, col2 FROM t1 DISTRIBUTE BY col1

SELECT col1, col2 FROM t1 DISTRIBUTE BY col1 SORT BY col1 ASC, col2 DESC
FROM (
  FROM pv_users
  MAP ( pv_users.userid, pv_users.date )
  USING 'map_script'
  AS c1, c2, c3
  DISTRIBUTE BY c2
  SORT BY c2, c1) map_output
INSERT OVERWRITE TABLE pv_users_reduced
  REDUCE ( map_output.c1, map_output.c2, map_output.c3 )
  USING 'reducer'
  AS date, count;
相关推荐
jumu20213 小时前
三菱FX5U与3台三菱E700变频器通讯实战
数据仓库
写代码的【黑咖啡】14 小时前
数据仓库中保障数据质量的关键环节:任务发布后数据校验
数据仓库
m0_7400437316 小时前
Spring_全面详解入门
数据仓库·hive·hadoop
皓空揽月16 小时前
windows安装hadoop2.7.2教程(单机版)
hadoop·windows
淡定一生233317 小时前
数据仓库基本概念
大数据·数据仓库·spark
亲亲菱纱1 天前
20251202
数据仓库
青云交2 天前
Java 大视界 -- Java 大数据在智能教育学习成果评估体系完善与教育质量提升中的深度应用(434)
java·hive·spark·智能教育·学习成果评估·教育质量提升·实时评估
SelectDB技术团队2 天前
面向 Agent 的高并发分析:Doris vs. Snowflake vs. ClickHouse
数据仓库·人工智能·科技·apache·知识图谱
德昂信息dataondemand2 天前
数据仓库性能优化:从模型到调度的系统性实践
数据仓库·性能优化
天天向上杰2 天前
小聊:银行数据仓库项目中 DEV → SIT → UAT → PRE-PROD → PROD
数据仓库