1. DQL 排序问题
1.1 order by
默认是升序asc,可指定降序desc。
order by是全局排序 只能有一个reduce作业来完成
多个reduce 如何保证全局顺序?
hive.mapred.mode
改为strict,则使用order by的时候有以下限制:
- 如果是普通表,则需要加 limit
- 如果是分区表则:
- 需要加 limit
- 需要限定分区条件
建议:慎用
1.2 sort by
mapred.reduce.tasks
指定reduce的个数
sort by能保证每个分区有序,你有几个reduce作业,每个reduce输出的结果是有序
sort by不受hive.mapred.mode=strict影响,col可以是多个。
如果数值是数值类型,那么按照数字排序
如果数值是字符串类型,那么按照字典顺序排序
- 补充:MR中多少个reduce作业就对应多少个输出文件。Spark中多少个task就对应多少个输出文件
1.3 distribute by
不是排序。+ col,根据指定的字段把数据分发到不同的reduce上去。相当于MapReduce中的Partitioner,通常与sort by连用
1.4 Cluster By
根据by的值的hash值进行分区和排序,分发到不同的reduce
当Distribute By和Sort By的字段相同是,就等价于cluster by
1.5 by总结
- order by:全局有序,只有一个reduce,大数据量下的场景下,效率低。相关参数
hive.mapred.mode
影响其是否需要加限制条件 - sort by:多个每个reduce内有序,不能保证全局有序。
mapred.reduce.tasks
指定reduce的个数,不受hive.mapred.mode
的影响。 - distribute by:是按照指定字段进行数据分发,常与sort by连用,确保每个reduce内有序。语句顺序,先 distribute by 再 sort by.
- cluster by = distribute by + sort by
思考:需求:业务统计结果要求有序。
order by用不了啊,sort by又不能保证全局有序,咋整????
(根据需要排序的字段查看字段值分布,先distribute by再sort by)