首页 » Web前端 » redisphpsortlimt技巧_Hive四种排序

redisphpsortlimt技巧_Hive四种排序

访客 2024-12-13 0

扫一扫用手机浏览

文章目录 [+]

它们的利用方法和性能又是如何呢?废话不多说,这篇文章就详细先容一下,欢迎收藏。

初始化数据

-- 建表create table testdb.tb_student( `id` bigint comment '学号', `name` string COMMENT '姓名', `course` string COMMENT '课程名称', `score` int COMMENT '分数')comment '用户课程分数表';-- 初始数据 INSERT OVERWRITE TABLE testdb.tb_studentSELECT id, name, course, scoreFROM ( SELECT 1 AS id, '张三' AS name, '语文' AS course, 81 AS score UNION ALL SELECT 1 AS id, '张三' AS name, '数学' AS course, 82 AS score UNION ALL SELECT 1 AS id, '张三' AS name, '英语' AS course, 83 AS score UNION ALL SELECT 2 AS id, '李四' AS name, '语文' AS course, 84 AS score UNION ALL SELECT 2 AS id, '李四' AS name, '数学' AS course, 85 AS score UNION ALL SELECT 2 AS id, '李四' AS name, '英语' AS course, 86 AS score UNION ALL SELECT 3 AS id, '王五' AS name, '语文' AS course, 84 AS score UNION ALL SELECT 3 AS id, '王五' AS name, '数学' AS course, 88 AS score UNION ALL SELECT 3 AS id, '王五' AS name, '英语' AS course, 89 AS score UNION ALL SELECT 4 AS id, '刘备' AS name, '语文' AS course, 84 AS score UNION ALL SELECT 4 AS id, '刘备' AS name, '数学' AS course, 91 AS score UNION ALL SELECT 4 AS id, '刘备' AS name, '英语' AS course, 92 AS score UNION ALL SELECT 5 AS id, '关羽' AS name, '语文' AS course, 93 AS score UNION ALL SELECT 5 AS id, '关羽' AS name, '数学' AS course, 94 AS score UNION ALL SELECT 5 AS id, '关羽' AS name, '英语' AS course, 85 AS score UNION ALL SELECT 6 AS id, '张飞' AS name, '语文' AS course, 96 AS score UNION ALL SELECT 6 AS id, '张飞' AS name, '数学' AS course, 97 AS score UNION ALL SELECT 6 AS id, '张飞' AS name, '英语' AS course, 98 AS score) t;order by(全局排序)

order by会对输入做全局排序,因此只有一个Reducer(多个Reducer无法担保全局有序),然而只有一个reducer,当输入规模较大时,会导致花费较长的打算韶光。

redisphpsortlimt技巧_Hive四种排序

降序:desc升序:asc 不须要指定,默认是升序

须要把稳的是它受hive.mapred.mode的影响,在严格模式下,必须利用limit 对排序的数据量进行限定,由于数据量很大只有一个reducer的话,会涌现OOM 或者运行韶光超长的情形,以是严格模式下,不适用limit 则会报错。

redisphpsortlimt技巧_Hive四种排序
(图片来自网络侵删)

Hive本地模式

0.7版本后Hive开始支持任务实行选择本地模式(local mode)大多数的Hadoop Job是须要Hadoop供应的完全的可扩展性来处理大数据的。

在hive中运行的sql有很多是比较小的SQL,数据量小并且打算量小 ,这些比较小的SQL如果也采取分布式的办法来实行,那么是得不偿失落的。

由于sql真正实行的韶光可能只有10秒,但是分布式任务的天生的其他过程的实行可能要1分钟。
这样的小任务更适宜采取lcoal mr的办法来实行,便是在本地来实行,通过把输入数据拉回客户端来实行。

启用办法 set hive.exec.mode.local.auto=true;(默认为false)

当一个job知足如下条件才能真正利用本地模式:

job的输入数据大小必须小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB)job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4)job的reduce数必须为0或者1 sort by(分区内排序)

它不是全局排序,其在数据进入reducer前完成排序,也便是说它会在数据进入reduce之前为每个reducer都产生一个排序后的文件。
因此,如果用sort by进行排序,并且设置mapreduce.job.reduces>1,则sort by只担保每个reducer的输出有序,不担保全局有序。

它不受Hive.mapred.mode属性的影响,sort by的数据只能担保在同一个reduce中的数据可以按指定字段排序。
利用sort by你可以指定实行的reduce个数(通过set mapred.reduce.tasks=n来指定),对输出的数据再实行归并排序,即可得到全部结果。

set mapred.reduce.tasks=2; select from testdb.tb_student sort by id;

创造上面的输出彷佛看不出来啥,只能看到不是有序的,这便是sort by不能担保全局有序的证明。

那我们换一种方法,将数据输出到文件,由于我们设置了reduce数是2,那该当会有两个文件输出

set mapred.reduce.tasks=2;insert overwrite local directory '/home/kn/workspace/hive/sort' row format delimited fields terminated by '\t' select from testdb.tb_student sort by id;

从运行结果上看,天生了四个文件,个中以_0结尾的存储的是SQL实行后输出的数据,看下内容,第一列是id,每个文件内的数据都是有序的。

sort by 和order by 的实行效率一样平常情形下我们认为sort by 该当是比 order by 快的,由于 order by 只能利用一个reducer,进行全部排序。
当数据量比较小的时,由于reducer 的启动耗时可能远远数据处理的韶光长,看下面实行结果耗时可知。

hive (testdb)> select from testdb.tb_student order by id;tb_student.id tb_student.name tb_student.course tb_student.score1 张三 语文 811 张三 数学 821 张三 英语 832 李四 语文 842 李四 数学 852 李四 英语 863 王五 英语 893 王五 数学 883 王五 语文 844 刘备 英语 924 刘备 数学 914 刘备 语文 845 关羽 语文 935 关羽 数学 945 关羽 英语 856 张飞 数学 976 张飞 英语 986 张飞 语文 96Time taken: 33.89 seconds, Fetched: 18 row(s)hive (testdb)> select from testdb.tb_student sort by id;tb_student.id tb_student.name tb_student.course tb_student.score1 张三 语文 811 张三 英语 832 李四 数学 852 李四 语文 843 王五 数学 884 刘备 英语 924 刘备 数学 914 刘备 语文 845 关羽 语文 936 张飞 英语 986 张飞 数学 976 张飞 语文 961 张三 数学 822 李四 英语 863 王五 语文 843 王五 英语 895 关羽 数学 945 关羽 英语 85Time taken: 37.099 seconds, Fetched: 18 row(s)

从实行日志上看,sort by 的reducer比order by 多,由于测试数据比较少,启动reducer又比较耗时,以是数据量少的时候sort by性能表示不出来。

order by : Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 1sort by :Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 2sort by 中的limt n

在sort by 后用limit子句减少数据量,sort by后利用limit n ,传输到reduce真个数据记录数就减少到 n m(m为map个数),也便是说在sort by中利用limit 限定的实际上是每个reducer打算的数据量,然后再根据sort by的排序字段进行order by排序,末了返回n 条数据给客户端,也便是说你在sort by 用limit子句,末了还是会利用order by 进行末了的排序。

order by 中利用limit 是对排序好的结果文件取limit n数据,然后交给reducer,可以看到sort by 中limit 子句会减少参与排序的数据量,而order by 中的弗成,只会限定返回客户端数据量的多少。

再看下两者的实行操持,可见sort by limit 比order by limit多了一个stage(order by limit),sort by limit实际上实行了两次limit,减少了参与排序的数据量。

distribute by(数据分发)

distribute by是掌握在map端如何拆分数据给reduce真个。
类似于MapReduce等分区partationer对数据进行分区。

hive会根据distribute by后面列,将数据分发给对应的reducer,默认是采取hash算法+取余数的办法。

sort by为每个reduce产生一个排序文件,在有些情形下,须要掌握某写特定的行该当分到哪个reducer,而为了后续的聚拢操作。
distribute by恰好可以做这件事,因此,distribute by常常和sort by合营利用。

例如上面的sort by 的例子中,我们创造不同id的数据并不在一个文件中,也就说不在同一个reducer 中,接下来我们看一下如何将相同的id输出在一起,然后按照id升序排序

首先我们考试测验一下没有distribute by 的SQL的实现,如下:

set mapred.reduce.tasks=2;insert overwrite local directory '/home/kn/workspace/hive/sort' row format delimited fields terminated by '\t' select from testdb.tb_student sort by score ;

结果如下图,相同id的学生并没有分到同一个文件中。

set mapred.reduce.tasks=2;insert overwrite local directory '/home/kn/workspace/hive/sort' row format delimited fields terminated by '\t' select from testdb.tb_student distribute by id sort by id,score ;

从实行结果上看,相同id的被分配到同一个文件中了。

cluster by

cluster by除了具有distribute by的功能外还兼具sort by的功能。
但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。

当分区字段和排序字段相同cluster by可以简化distribute by+sort by 的SQL 写法,也便是说当distribute by和sort by 字段相同时,可以利用cluster by 代替distribute by和sort by

set mapred.reduce.tasks=2;insert overwrite local directory '/home/kn/workspace/hive/sort' row format delimited fields terminated by '\t' select from testdb.tb_student distribute by id sort by id ;

上面SQL等价于下面的

set mapred.reduce.tasks=2;insert overwrite local directory '/home/kn/workspace/hive/sort' row format delimited fields terminated by '\t' select from testdb.tb_student cluster by id;

通过上面两个SQL实行结果是一样的,这也就证明了当distribute by和sort by 字段相同时,可以利用cluster by 代替distribute by和sort by。

当你考试测验给cluster by 指定排序方向的时候,你就会得到如下缺点:

hive (testdb)> select from testdb.tb_student cluster by id desc;FAILED: ParseException line 1:46 extraneous input 'desc' expecting EOF near '<EOF>'总结

Hive 中有以下四种排序办法:

`ORDER BY`:按照指定的列或表达式对结果集进行排序。
这是最常见的排序办法,默认升序排序。
`SORT BY`:与`ORDER BY`类似,但可以在`MAP`或`REDUCE`阶段进行排序,适用于分布式打算环境。
`DISTRIBUTE BY`:在`MAP`阶段根据指定的列将数据分发到不同的节点进行处理,用于分布式数据处理。
`CLUSTER BY`:与`DISTRIBUTE BY`类似,但还会对相同分发值的数据进行局部排序,常用于`GROUP BY`操作。

这些排序办法在 Hive 中都有各自的用场和特点,可以根据详细的需求选择得当的办法进行排序和数据分发。

你学会了吗?欢迎点赞收藏,分享转载~~

标签:

相关文章