最近有重新回看了《Hadoop權威指南》,又想起來總結一些博文了,所以針對Hive常用函數和性能調優又仔細查了很多資料,寫了這篇文章,還是一樣,感謝各位在網絡上的分享!!!
博客分享:
https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties
一.Hive常用函數
1.時間處理函數
函數名稱 | 返回值 | 作用 | 備註 |
current_date() | string | 返回當天時間 | 返回時間格式‘yyyy-MM-dd’ |
unix_timestamp() | bigint | 返回當前時區的時間戳 | |
from_unixtime(bigint unixtime[, string format]) | string | 返回Unix時間戳轉日期格式 | 可以通過format定義返回結果樣式 |
unix_timestamp(string date,string pattern) | bigint | 返回制定格式轉化至時間戳 | 轉化失敗返回0 |
to_date(string date) | string | 返回時間字段中的日期部分 | 格式錯誤返回null |
year(string date) | int | 返回時間字段中的‘年’部分 | month,day,hour,minute,second使用方法相同 |
datediff(string enddate,string startdate) | int | 返回(結束日期-開始日期)的數值 | 僅返回時間上的天數差距 |
2.類型轉換函數
隱式類型轉換:所有整數類型都可以隱式轉換爲一個範圍更廣的類型。所有整數類型 + float + String都可以轉換爲Double類型。時間戳和日期可以隱式地轉換成文本類型。BOOLEAN不能做任何的類型轉換。
顯式類型轉換:
cast( 表達式a as 數據類型b ):可以將表達式a的數據類型顯式的轉化爲數據類型b,並且轉化失敗會返回null。
3.條件判斷函數
函數名稱 | 返回值 | 作用 | 備註 |
if(boolean condition, T valueTrue, T valueFalse) | T |
判斷condition的正誤 正確則返回valueTrue,錯誤則返回valueFalse |
|
coalesce(T value1,T value2,...) | T | 返回參數列表中第一個非空數值 | 如果所有數值均爲null,則返回null |
case when conditionA then answerB else answerC end | T | 如果conditionA成立,則返回answerB否則返回answerC | 可以連續 [when a then b] 對多種情況進行判斷和結果返回 |
4.空值判斷函數
hive表中默認將null存儲爲\N。可以使用is null和is not null來判斷某值是否是空值。可以結合條件判斷函數使用( if( valueA is null ,'true' , 'false' ) )。
也可以直接使用nvl()函數對數值列進行處理,同理還可以使用條件判斷函數中的coalesce()函數。
nvl( 表達式a , 表達式b ):判斷表達式a是否爲null,若是則返回表達b,若不是則返回表達式a。等價於 if( 表達式a is null ,表達式b , 表達式a ) 。
if函數和nvl函數的區別:兩者的區別在於if函數的參數值類型可以不同,但是nvl函數的參數類型必須爲同類型。
在處理空字符串 '' 時,可以使用 a = '' 或者 a <> ''進行判斷。
5.字符串處理函數
函數名稱 | 返回值 | 作用 | 備註 |
length(string a) | int | 返回字符串a的長度 | |
reverse(string a) | string | 返回字符串a的字符串結果翻轉 | |
concat(string a, string b,…) | string | 返回字符串a和字符串b和...的字符串拼接結果 | |
concat_ws(string sepString, string a, string b,…) | string | 返回字符串a和字符串b和...的字符串拼接結果,且字符串之間使用sepString連接 | |
substr(string a,int start[,int end]) | string | 返回字符串a從start位置開始到末尾【到end】截取出來的字符串 | |
upper(string a)/ucase(string a) | string | 返回字符串a的大寫格式 | lower(string a)和lcase(string a)返回字符串a的小寫格式 |
trim(string a) | string | 返回字符串a去除前後兩端空格的字符串 | ltrim(string a)和rtrim(string a)單獨去除左端/右端空格 |
regexp_replace(string a, string pattern, string b) | string | 將字符串a中符合正則表達式字符串pattern的內容替換爲字符串b的內容 | 正則表達式pattern字符串需要注意轉義 |
regexp_extract(string a, string pattern, int index) | string | 將字符串a按照正則表達式字符串pattern的內容拆分,並且返回下標爲index的內容 | 類似於replace()函數中的小括號和$取值的方式,下標0爲原始字符串 |
split(string a, string b) | array | 將字符串a按照字符串b進行分割,返回字符串數組 | 注意轉義 |
instr(string a, string b) | int | 若字符串b在字符串a中存在則返回具體位置(int),不存在則返回0 | |
parse_url(string a, string partUrl[, string key]) | string | 解析url字符串a,並且根據具體所需partUrl返回對應位置數據信息。也可通過使用‘QUERY’和具體的key返回指定的參數數值 |
partUrl可使用的參數包括: [HOST(域名),PATH(路徑),QUERY(參數),REF(定位), PROTOCOL(協議)FILE(路徑+參數),AUTHORITY(域名),USERINFO] |
parse_url_tuple(string a, string partUrl[, string key]) | string | 解析url字符串a,用法與parse_url類似,可以同時返回多個key的value值 | |
get_json_object(string a string path) | string | 解析json字符串a,並且根據path獲取json字符串中對應key的value值 |
字符串a必須符合json格式,若字符串無效則返回null |
json_tuple(string a, string keyValue,...) | string | 解析json字符串a,並且根據keyValue取得對應key的value值 | get_json_object可以處理更加複雜的json,json_tuple可以處理一次想取出多個key的場景 |
lpad(string a, int len, string b) | string | 將字符串a左側用字符串b補全至長度爲len | rpad(string a, int len, string b)作用於右側 |
find_in_set(string a, string strList) | int | 返回字符串a在strList中出現的位置(strList必須是用逗號分隔的字符串) | 如果沒有找到對應字符,則返回0 |
6.其他類型處理函數
函數名稱 | 返回值 | 作用 | 備註 |
explode() |
用於array類型數據時,array中每個元素生成一行 用於map類型數據時,map中每個鍵值對一行,key/value各自一列 |
不能關聯原有的表中的其他字段。不能與group by、cluster by、distribute by、sort by聯用。不能進行UDTF嵌套。不允許選擇其他表達式。 |
|
array_contains(array, T b) | T/F | 用於判斷array類型數據中是否存在T類型的b | 可用於where條件查詢語句 |
lateral view explode(array) |
用於將單行array類型數據拆分爲分開的多行數據結果集 array位置爲想拆分的數組字段,單獨拆分一列,相當於是該列產生的結果集與原表進行笛卡爾積,也可以同時拆分多列 |
||
collect_list(arrayName) | 將分組中的某列轉爲一個數組返回,不去重 | ||
collect_set(arrayName) | 將分組中的某列轉爲一個數組返回,去重 |
7.分析窗口函數
用於分區排序( over( partition by ) ),動態group by,計算topN( row_number() )等場景。
定義window子句(eg. : rows between current row and 2 preceding),如果不指定ROWS BETWEEN,默認是從起點到當前行:
2 PRECEDING:前兩行
2 FOLLOWING:後兩行
CURRENT ROW:當前行
UNBOUNDED:起點
UNBOUNDED PRECEDING:從前面的起點
UNBOUNDED FOLLOWING:從後邊的終點
函數名稱 | 返回值 | 作用 | 備註 |
rank() | 序列函數 |
並列跳躍排名:在返回排名結果字段中並列名次的下一名將爲並列數量+並列名次(如並列第一兩名,則排行爲1,1,3) 不支持window子句 |
|
dense_rank() | 序列函數 |
並列不跳躍排名:在返回排名結果字段中並列名次的下一名將爲正常名次(如並列第一兩名,則排行爲1,1,2) 不支持window子句 |
|
row_number() | 序列函數 |
順序排序:在返回排名結果字段中無視並列名次(如並列第一兩名,則排行爲1,2,3) 不支持window子句 |
|
first_value() | 取值函數 | 返回當前排序分組內第一個數據的值(也可通過改變排序次序獲取最大值或最小值) | |
last_value() | 取值函數 | 返回當前排序分組內最後一個數據的值(也可通過改變排序次序獲取最大值或最小值) | |
ntile(int a) | 序列函數 |
將返回結果分爲a份,可用於取百分比數量數據 |
|
lag(string lineName[, int a]) | 上提函數 | 用於統計窗口內往上第n行值 第一個參數爲列名,第二個參數爲往上第n行(可選,默認爲1),第三個參數爲默認值(當往上第n行爲NULL時候,取默認值,如不指定,則爲NULL) |
|
lead(string lineName[, int a]) | 下沉函數 |
作用同上,往下第n行值,其餘相同 |
|
cume_dist() | 序列函數 | 用於統計指定值佔總數的百分比 |
二.Hive性能調優
1.Hive配置調優(https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties)
所有黑體+下劃線一般都不會選擇默認值,用於調優,而所有正常字體一般可選擇默認值。
配置語句 | 默認值 | 配置作用 | 備註 |
hive.auto.convert.join | false |
是否啓用Hive基於輸入文件大小的,將普通join轉換爲mapjoin的優化 MapJoin是常用的優化操作,適用於小表JOIN大表的場景,由於表的JOIN操作是在Map端且在內存進行的,所以其並不需要啓動Reduce任務也就不需要經過shuffle階段,從而能在一定程度上節省資源提高JOIN效率 |
該參數爲true時,Hive自動對左邊的表統計量,如果是小表就加入內存,即對小表使用mapjoin |
hive.mapjoin.smalltable.filesize | 25000000 | 小表的輸入文件大小的閾值(單位:字節);如果文件大小小於此閾值,它將嘗試將普通join轉換爲mapjoin | 該參數作爲大表,小表判斷的閾值,如果表的大小小於該值則會被加載到內存中運行 |
hive.auto.convert.join.noconditionaltask | true | 是否啓用Hive基於輸入文件大小的,將普通join轉換爲mapjoin的優化 | 將普通join轉換爲mapjoin時,是否將多個mapjoin轉換爲一個mapjoin |
hive.auto.convert.join.noconditionaltask.size | 10000000 | 將普通join轉換爲mapjoin時,最多可以將最大值爲多少的小錶轉換爲一個mapjoin | 多個mapjoin轉換爲1個時,所有小表的文件大小總和的最大值 |
hive.exec.parallel | false | 是否並行執行jobs,適用於可以並行執行的MapReduce job | |
hive.exec.parallel.thread.number | 8 | 設定最多可以並行執行多少個job | 代表一次 SQL 計算中允許並行執行的 job 個數的最大值 |
hive.execution.engine | mr(2.0.0後棄用) | 選擇執行引擎。可選項有MapReduce,Tez和Spark | 當執行引擎發生改變時,可以通過對對應引擎進行調優達到對hive語句執行的優化 |
mapred.reduce.tasks | -1 |
默認每一個job對應的reducer的數量,通常設定爲可用主機的近似值 |
|
hive.exec.reducers.bytes.per.reducer | 256000000 | 每一個reducer處理的數據量大小 | |
hive.exec.reducers.max | 1009 | 每一個job最大可以使用的reducer數量 | |
hive.map.aggr | true | 在使用group by查詢語句時,是否使用map端聚合 | |
hive.groupby.mapaggr.checkinterval | 100000 | 在map端group by聚合時處理的數據行數 | |
hive.map.aggr.hash.min.reduction=0.5; | 0.5 | 進行聚合的最小比例,如果聚合後數據量和處理的數據行數的比值大於該數字,則將關閉聚合。設置爲1可以確保從未關閉聚合 | |
hive.map.aggr.hash.percentmemory | 0.3 | 當使用map端group by聚合時,map端聚合可使用的內存上限 | |
hive.groupby.skewindata | false | 在使用group by時是否進行數據傾斜優化 |
2.Hive語句調優
(1).在表連接時將小表放在前邊,大表放在後邊。Hive會採取將小表都放在內存中,而後掃描大表的方式。
(2).慎重使用COUNT(DISTINCT col),distinct會將數據保存在內存中,加快速度,但是可能會發生OOM,可以通過使用ROW_NUMBER() OVER(PARTITION BY col)等方式替代。
(3).儘量不使用select *而是使用具體字段進行查詢操作。
(4).儘量採取謂詞下推(將數據過濾表達式儘可能的移動至靠近數據源的位置,以便儘可能早的處理表達式語句和儘可能少的處理無關數據)的方式書寫語句。
(5).儘可能不使用order by語句或在使用order by語句時同limit語句一齊使用,否則可能會導致只有一個reducer運行的結果。