Hive学习之SELECT语句(二)

ORDER BY从句

      Hive中的order by从句与SQL中的order by很相似,都支持ASC和DESC,语法格式如下:

ORDER BY colName[ASC|DESC]

      但Hive中的order by有一些限制。在严格模式下(hive.mapred.mode=strict),order by从句后面必须跟着limit从句,如果hive.mapred.mode= nonstrict(默认值),则limit从句不是必须的。原因是为了使所有结果有序,必须有一个reducer对最终输出进行排序,如果输出的行数太多,单个reducer可能需要太多时间完成。

SORT BY从句

      SORT BY与ORDER BY的语法格式相似,如下:

SORT BY colName [ASC|DESC]

      Hive使用SORT BY在传输行到reducer之前对行排序。排序次序依赖于列的类型,如果列是数值型的,排序按照数值顺序,如果列是字符类型,排序按照字典顺序。

      SORT BY与ORDER BY的不同是,前者保证输出中的总体顺序,后者保证某个reducer中行的顺序。如果存在多个reducer,SORT BY可能产生部分有序的最终结果。

      在转换后,变量类型通常被做为字符串,也就意味着数值数据将会按照字典顺序排序。为了克服这一问题,带有casts的第二个select语句可以在SORT BY之前使用,如下:

FROM (FROM (FROMsrc
            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
SELECTTRANSFORM(value, count)
USING 'reducer'
AS whatever

Cluster By和Distribute By从句

      Cluster By和Distribute By主要与Transform/Map-Reduce脚本一起使用,但如果select语句需要为后续查询分区和排序输出,则还是有用的。Cluster By是Distribute By和Sort By的简捷方式。Hive使用Distribute By中的列在reducers之间分配行,所有拥有相同DistributeBy中列的行将被分配到相同的reducer中,但是Distribute By不保证分配键上的聚类或者排序属性。例如,在下面的5列中使用Distribute By x到2个reducer:

      x1

      x2

      x4

      x3

      x1

      Reducer 1得到:x1  x2  x1

      Reducer 2得到:x4  x3

      通过上面的结果可以发现,相同的键x1确保分配到相同的reducer—reducer1,但不确保它们被聚类到邻近的位置。相反,如果使用cluster by x,reducers将进一步在x上排序行:

      Reducer 1得到:x1  x1  x2

      Reducer 2得到:x3  x4

      可以使用Distribute By和Sort By替代Cluster By,这样分区列和排序列可以是不同的。通常情况,分区列做为排序列的前缀,但这不是必需的,例子如下:

SELECT col1,col2 FROM t1 DISTRIBUTE BY col1
 
SELECT col1, col2FROM 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 OVERWRITETABLE pv_users_reduced
  REDUCE ( map_output.c1, map_output.c2,map_output.c3 )
  USING 'reduce_script'
  AS date, count;

虚拟列

      Hive支持两个虚拟列,分别为:INPUT__FILE__NAME、BLOCK__OFFSET__INSIDE__FILE和ROW__OFFSET__INSIDE__BLOCK。前者表示Mapper任务的输入文件名,第二个表示当前全局文件的位置,第三个表示块中行的偏移量,默认不启用该列,可以使用hive.exec.rowoffset=true启用该虚拟列。对于块压缩文件,表示当前块文件的偏移,这是当前块的第一个字节的文件偏移量。需要注意的是上述两个列名中包含的双下划线__。例如:

select input__file__name,block__offset__inside__file from idp limit 1;
Total MapReduceCPU Time Spent: 2 seconds 850 msec
OK
hdfs://hadoop:9000/user/hive/warehouse/logdb.db/idp/createdate=2014-03-03/source=1/iis.log   0
Time taken:42.401 seconds, Fetched: 1 row(s)

 

你可能感兴趣的:(hive,cluster,sort,by,by,by,虚拟列,distribute)