HIVE簡介
Hive是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射為一張數據庫表,並提供簡單的sql查詢,可以將sql語句轉換為MapReduce任務進行運行
同時,hive也允許熟悉map-reduce的開發者開發自定義的mapper和reducer來處理內建的mapper和reducer無法處理的復雜的分析工作。
用戶發出sql命令----> hive處理並轉換為MapReduce---->提交任務到hadoop並運行在hdfs
HIVE DDL
Hive建表(壓縮表和非壓縮表)
一個表可以擁有一個或者多個分區,每個分區以文件夾的形式單獨存在於表文件夾的目錄下
創建表:指定exterbal關鍵字的就是外部表,沒有就是內部表。內部表在drop的時候會從hdfs上刪除數據,外部表不會刪除
如果不指定數據庫,hive會把表創建在默認數據庫下。
創建內部表:
create table if not exists `my_inner_table`( `id` bigint comment '邏輯id,記錄的唯一id', `user_id` string comment 'user_id' ) comment '內部表' partitioned by (`dt` string comment 'date, yyyy-MM-dd') ROW FORMAT DELIMITED FIELDS TERMINATED BY '\001' lines terminated by '\n' STORED AS TEXTFILE
創建外部表:
create external table if not exists `my_external_table`( `id` bigint comment '邏輯id,記錄的唯一id', `user_id` string comment 'user_id' ) comment '外部表' partitioned by (`dt` string comment 'date, yyyy-MM-dd') ROW FORMAT DELIMITED FIELDS TERMINATED BY '\001' lines terminated by '\n' STORED AS TEXTFILE location 'hdfs://user/user.sql/';
HIVE SQL優化
優化的根本思想:
- 盡早盡量過濾數據,減少每個階段的數據量
- 減少job數
- 解決數據傾斜問題
盡早盡量過濾數據,減少每個階段的數據量
1.列裁剪:
例如某表有a,b,c,d,e五個字段,但是我們只需要a和b,那么請用select a,b from table 而不是select * from table
2.分區裁剪:
在查詢的過程中減少不必要的分區,即盡量指定分區
3.利用hive的優化機制減少job數:
不論是外關聯outer join還是內關聯inner join,如果join的key相同,不管有多少表,都會合並為一個MapReduce任務:
select a.val,b.val,c.val from a JOIN b ON (a.key = b.key1) JOIN c ON (c.key2 = b.key1) ----一個job select a.val,b.val,c.val from a JOIN b ON (a.key = b.key1) JOIN c ON (c.key2 = b.key2) ----兩個job
4.善用multi-insert:
#查詢了兩次a insert overwrite table tmp1 select ... from a where 條件1; insert overwrite table tmp2 select ... from a where 條件2; #查詢了一次a from a insert overwrite table tmp1 select ... where 條件1 insert overwrite table tmp2 select ... where 條件2
5.善用union all:
不同表的union all相當於multi inputs,同一表的union all相當於map一次輸出多條
6.避免笛卡爾積:關聯的時候一定要寫關聯條件
7.join前過濾掉不需要的數據
#hive0.12之前,會先把a全部數據和b的全部數據進行了關聯,然后再篩選條件,0.12之后做了優化 1. select a.val,b.val from a LEFT OUTER JOIN b ON (a.key=b.key)where a.dt='2020-05-07' and b.dt='2020-05-07' #優化后的方案 2.select x.val,y.val from (select key, val from a where a.dt='2020-05-07') x LEFT OUTER JOIN (select key, val from b where b.dt='2020-05-07') y ON x.key=y.key
8.小表放前大表放后
在編寫帶有join的代碼語句時,應該將條目少的表/子查詢放在join操作符的前面
因為在Reduce階段,位於join操作符左邊的表會先被加載到內存,載入條目較少的表可以有效的防止內存溢出(OOM)。所以對於同一個key來說,對應的value值小的放前面,大的放后面
9.在map階段進行join
join階段有兩種,一種是在map階段進行的,一種是在reduce階段進行的。當小表和大表進行join時,盡量采用mapjoin,即在map端完成,盡早結合數據,使reduce端接收數據量減少。同時可以避免小表與大表join產生的數據傾斜。
如果一個表特別小,推薦用mapjoin;如果不是,我們一般用reduce join
MAPJOIN寫法:
select /*+ MAPJOIN(b) */ a.value,b.value from a join b on a.key=b.key
10.hive0.13之前實現IN和EXISTS
LEFT SEMI JOIN是IN和EXISTS的一種高效實現,在hive0.13之前是不支持IN和EXISTS的
1.select a.key,a.value from a where a.key in (select b.key from b)(hive0.13前不支持) 2.select a.key,a.value from a left outer join b on a.key=b.key where b.key is not null 3.select a.key,a.value from a left semi join b on a.key=b.key 4.select a.key,a.value from a JOIN b ON (a.key=b.key)
LEFT SEMI JOIN產生的數據不會重復。
11.使用動態分區
set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; create table my_table( id bigint ) partitioned by(dt string) STORED AS TEXTFILE; insert overwrite table my_table partition(dt) select id,dt from tmp_table
12.union all優化
hive0.13之前不支持union all直接放外層,必須外層套一個查詢,例如:
select key,value from a union all select key,value from b
是不支持的。
hive對union all的優化只局限於非嵌套查詢。
select * from( select key,value from a group by key,value union all select key,value from b group by key,value ) ---- 三個job select key,value from( select key,value from a union all select key,value from b ) as tmp group by tmp.key,tmp.value ---- 一個job,用於小表
不同表太多的union all,不推薦使用。可以寫在中間表的不同分區里,然后再進行union all
13.盡量避免使用distinct
盡量避免使用distinct進行重排,特別是大表,容易產生數據傾斜(key一樣在一個reduce處理)。使用group by替代
select distinct key from a select key from a group by key
14.排序優化
只有order by產生的結果是全局有序的,可以根據實際場景進行選擇排序
- order by實現全局排序,一個reduce實現,由於不能並發執行,所以效率低
- sort by實現部分有序,單個reduce的輸出結果是有序的,效率高,通常與distribute by一起使用(distribute by 關鍵詞可以指定map到reduce的key分發)
- cluster by col1等價於distribute by col1 sort by col1,但不能指定排序規則
15.使用explain dependency查看sql實際掃描多少分區
轉載請注明出處:https://www.cnblogs.com/fnlingnzb-learner/p/13087976.html