在這里解釋一下select語法中的order by、sort by、distribute by、cluster by、order by語法。
一、order by語法
在hiveQL中Order by語法類似於sql語言中的order by語法。
colOrder: ( ASC | DESC ) colNullOrder: (NULLS FIRST | NULLS LAST) -- (Note: Available in Hive 2.1.0 and later) orderBy: ORDER BY colName colOrder? colNullOrder? (',' colName colOrder? colNullOrder?)* query: SELECT expression (',' expression)* FROM src orderBy |
有一些限制在order by子句中,在嚴格模式下(strict),order by子句必須帶有以limit子句。Limit子句不是必須的,如果你設置hive.mapred.mode是非嚴格模式(nostrict)。原因是為了增強全局排序的結果,這里只有一個reduce去進行最終的排序輸出,如果輸出結果集行集太大,這單獨的reduce可能需要花費非常長的時間去處理。
注意,這列必須使用的名字,而不能指定位置號,然而在hive 0.11.0以后,在做了下面配置之后列可以指定序列號,如下:
1)從hive0.11.0到2.1.x,設置hive.groupby.orderby.position.alias 是true(默認值是false)。
2)從hive2.2.0以后,hive.orderby.position.alias默認是ture。
Order by默認排序是asc。
在hive 2.1.0以后,被選擇排序的每個列是null在order by子句是支持的。默認null排序規則是asc(升序)是nulls first,當默認的排序規則是desc(時)是nulls last
二、sort by語法
在hiveQL中sort by語法類似於sql語言中的order by語法。
colOrder: ( ASC | DESC ) sortBy: SORT BY colName colOrder? (',' colName colOrder?)* query: SELECT expression (',' expression)* FROM src sortBy |
Hive中被用來sort by排序的行的排序操作發生在發送這些行到reduce之前。排序的次序依賴於排序列的類型,如果列是數值類型,那么排序次序按照數值排序,如果列式字符串類型,那么排序次序將按照字典排序。
1、sort by和order by的不同點
Hive sort by的排序發生在每個reduce里,order by和sort by之間的不同點是前者保證在全局進行排序,而后者僅保證在每個reduce內排序,如果有超過1個reduce,sort by可能有部分結果有序。
注意:它也許是混亂的作為單獨列排序對於sort by和cluster by。不同點在於cluster by的分區列和sort by有多重reduce,reduce內的分區數據時一致的。
通常,數據在每個reduce排序通過用戶指定的規則,如下示例:
SELECT key, value FROM src SORT BY key ASC, value DESC |
查詢有兩個reduce,查詢結果如下:
0 5 0 3 3 6 9 1 |
0 4 0 3 1 1 2 5 |
2、設置排序類型
轉換后,參數類型一般認為是string類型,意味着數值類型將按照字典排序方式進行排序,克服這一點,第二個select語句可以在sort by之前被使用。
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 by和distribute by主要用在進行Transform/Map-Reduce腳本。但是,他有時可以應用在select語句,如果有一個子查詢需要分區和排序對於輸出結果集。
Cluster by是一個捷徑對於包含distribute by和sort by的語句。
Hive使用distribute by中的列去分發行到每個reduce中,所有同樣的distribute by列的行將發送到同一個reduce。然而,分發並不保證clustering和sorting的屬性在分發關鍵字。
例如,我們按照x進行distribute by在5行數據到2個reduce中:
|
Reduce 1 得到的數據:
|
Reduce 2 得到的數據:
|
注意:這所有制是x1的行確保被分發到通一個reduce中,但是,他們不能保證在集合中會在相鄰的位置。
相比之下,如果我們使用cluster by x,這兩個reduce將進一步在x上進行排序。
Reduce 1得到數據:
x1 x1 x2 |
Reduce 2得到數據:
x3 x4 |
不能替代cluster by,用戶可以指定distribute by和sort by,同樣,分區列和排序列可以是不同的,通常情況,分區類是排序類的前綴,但是他並不是必須的。
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 'reduce_script' AS date, count; |