當前位置:首頁 » 編程語言 » 執行hivesql
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

執行hivesql

發布時間: 2023-08-20 14:43:28

A. 大數據開發工程師Hive(Hive sql的執行順序)

Hive中SQL的執行順序:

(1) from :對from左邊的表和右邊的表計算笛卡爾積,產生虛表VT1;

(2) on : 對虛表VT1進行on過濾,只有那些符合 的行才會被記錄在虛表VT2中;

(3) join :如果指定了outer join(比如left join、 right join),那麼保留表中未匹配的行就會作為外部行添加到虛擬表VT2中,產生虛擬表VT3;

(4) where :對虛擬表VT3進行where條件過濾。只有符合 的記錄才會被插入到虛擬表VT4中;

(5) group by :根據group by子句中的列,對VT4中的記錄進行分組操作,產生VT5;

(6) having : 對虛擬表VT5應用having過濾,只有符合 的記錄才會被 插入到虛擬表VT6中;

(7) select :執行select操作,選擇指定的列,插入到虛擬表VT7中;

(8) distinct :對VT7中的記錄進行去重。產生虛擬表VT8;

(9) order :將虛擬表VT8中的記錄按照 進行排序操作,產生虛擬表VT9;

(10) limit :取出指定行的記錄,產生虛擬表VT10, 並將結果返回;

partition by 通常會用於和開窗及分析函數一起使用,partition by是在select執行完 的結果集上進行的;


(每日1小題,進步1點點)

B. Hive SQL語句執行順序

Hive 中 sql 語句的執行順序如下:

from .. where .. join .. on .. select .. group by .. select .. having .. distinct .. order by .. limit .. union/union all

下面我們通過一個 sql 語句分析下:

上面這條 sql 語句是可以成功執行的,我們看下它在 MR 中的執行順序:

Map 階段

Rece 階段

上面這個執行順序到底對不對呢,我們可以通過 explain 執行計劃來看下,內容過多,我們分階段來看。

我們看到 Stage-5 是根,也就是最先執行 Stage-5,Stage-2 依賴 Stage-5,Stage-0 依賴 Stage-2。

圖中標 ① 處是表掃描操作,注意先掃描的 b 表,也就是 left join 後面的表,然後進行過濾操作(圖中標 ② 處),我們 sql 語句中是對 a 表進行的過濾,但是 Hive 也會自動對 b 表進行相同的過濾操作,這樣可以減少關聯的數據量。

先掃描 a 表(圖中標 ① 處);接下來進行過濾操作 idno > �'(圖中標 ② 處);然後進行 left join,關聯的 key 是 idno(圖中標 ③ 處);執行完關聯操作之後會進行輸出操作,輸出的是三個欄位,包括 select 的兩個欄位加 group by 的一個欄位(圖中標 ④ 處);然後進行 group by 操作,分組方式是 hash(圖中標 ⑤ 處);然後進行排序操作,按照 idno 進行正向排序(圖中標 ⑥ 處)。

首先進行 group by 操作,注意此時的分組方式是 mergepartial 合並分組(圖中標 ① 處);然後進行 select 操作,此時輸出的欄位只有兩個了,輸出的行數是 30304 行(圖中標 ② 處);接下來執行 having 的過濾操作,過濾出 count_user>1 的欄位,輸出的行數是 10101 行(圖中標 ③ 處);然後進行 limit 限制輸出的行數(圖中標 ④ 處);圖中標 ⑤ 處表示是否對文件壓縮,false 不壓縮。

限制最終輸出的行數為 10 行。

通過上面對 SQL 執行計劃的分析,總結以下幾點:

C. hive執行sql:stage-1 map = 0 rece = 0

問題描述:
在hive shell中執行sql,如
insert into person_base1 select * from person_base;

運行日誌中一直顯示如下信息

解決方式:
修改yarn-site.xml中的yarn.nodemanager.resource.memory-mb值大小(2G->4G)
原先設置

修改後設置

D. 如何在Java中執行Hive命令或HiveQL

Java在1.5過後提供了ProcessBuilder根據運行時環境啟動一個Process調用執行運行時環境下的命令或應用程序(1.5以前使用Runtime),關於ProcessBuilder請參考Java相關文檔。調用代碼如下:
String sql="show tables; select * from test_tb limit 10";
List<String> command = new ArrayList<String>();
command.add("hive");
command.add("-e");
command.add(sql);
List<String> results = new ArrayList<String>();
ProcessBuilder hiveProcessBuilder = new ProcessBuilder(command);
hiveProcess = hiveProcessBuilder.start();
BufferedReader br = new BufferedReader(new InputStreamReader(
hiveProcess.getInputStream()));
String data = null;
while ((data = br.readLine()) != null) {
results.add(data);
}
其中command可以是其它Hive命令,不一定是HiveQL。

E. hive運行sql rece 為1 ,跑不動怎麼處理

1.jpg 優化可以從幾個方面著手:1. 好的模型設計事半功倍。2. 解決數據傾斜問題。3. 減少job數。4. 設置合理的map rece的task數,能有效提升性能。(比如,10w+級別的計算,用160個rece,那是相當的浪費,1個足夠)。5. 自己動手寫sql解決數據傾斜問題是個不錯的選擇。set hive.groupby.skewindata=true;這是通用的演算法優化,但演算法優化總是漠視業務,習慣性提供通用的解決方法。 Etl開發人員更了解業務,更了解數據,所以通過業務邏輯解決傾斜的方法往往更精確,更有效。6. 對count(distinct)採取漠視的方法,尤其數據大的時候很容易產生傾斜問題,不抱僥幸心理。自己動手,豐衣足食。7. 對小文件進行合並,是行至有效的提高調度效率的方法,假如我們的作業設置合理的文件數,對雲梯的整體調度效率也會產生積極的影響。8. 優化時把握整體,單個作業最優不如整體最優。

F. Hive sql及窗口函數

hive函數:

1、根據指定條件返回結果:case when then else end as

2、基本類型轉換:CAST()

3、nvl:處理空欄位:三個str時,是否為空可以指定返回不同的值

4、sql通配符: https://www.w3school.com.cn/sql/sql_wildcards.asp

5、count(1)與COUNT(*):返回行數

如果表沒有主鍵,那麼count(1)比count(*)快;

如果有主鍵,那麼count(主鍵,聯合主鍵)比count(*)快;

count(1)跟count(主鍵)一樣,只掃描主鍵。count(*)跟count(非主鍵)一樣,掃描整個表。明顯前者更快一些。

性能問題:

1.任何情況下SELECT COUNT(*) FROM tablename是最優選擇,(指沒有where的情況);

2.盡量減少SELECT COUNT(*) FROM tablename WHERE COL = 『value』 這種查詢;

3.杜絕SELECT COUNT(COL) FROM tablename WHERE COL2 = 『value』 的出現。

count(expression):查詢 is_reply=0 的數量: SELECT COUNT(IF(is_reply=0,1,NULL)) count FROM t_iov_help_feedback;

6、distinct與group by

distinct去重所有distinct之後所有的欄位,如果有一個欄位值不一致就不作為一條

group by是根據某一欄位分組,然後查詢出該條數據的所需欄位,可以搭配 where max(time)或者Row_Number函數使用,求出最大的一條數據

7、使用with 臨時表名 as() 的形式,簡單的臨時表直接嵌套進sql中,復雜的和需要復用的表寫到臨時表中,關聯的時候先找到關聯欄位,過濾條件最好在臨時表中先過濾後關聯

處理json的函數:

split(json_array_string(schools), '\\|\\|') AS schools

get_json_object(school, '$.id') AS school_id,

字元串函數:

1、instr(』源字元串』 , 『目標字元串』 ,』開始位置』,』第幾次出現』)

instr(sourceString,destString,start,appearPosition)

1.sourceString代表源字元串; destString代表要從源字元串中查找的子串;

2.start代表查找的開始位置,這個參數可選的,默認為1;

3.appearPosition代表想從源字元中查找出第幾次出現的destString,這個參數也是可選的, 默認為1

4.如果start的值為負數,則代表從右往左進行查找,但是位置數據仍然從左向右計算。

5.返回值為:查找到的字元串的位置。如果沒有查找到,返回0。

最簡單例子: 在abcd中查找a的位置,從第一個字母開始查,查找第一次出現時的位置

select instr(『abcd』,』a』,1,1) from al; —1

應用於模糊查詢:instr(欄位名/列名, 『查找欄位』)

select code,name,dept,occupation from staff where instr(code, 『001』)> 0;

等同於 select code, name, dept, occupation from staff where code like 『%001%』 ;

應用於判斷包含關系:

select ccn,mas_loc from mas_loc where instr(『FH,FHH,FHM』,ccn)>0;

等同於 select ccn,mas_loc from mas_loc where ccn in (『FH』,』FHH』,』FHM』);

2、substr(string A,int start,int len)和 substring(string A,int start,int len),用法一樣

substr(time,1,8) 表示將time從第1位開始截取,截取的長度為8位

第一種用法:

substr(string A,int start)和 substring(string A,int start),用法一樣

功效:返回字元串A從下標start位置到結尾的字元串

第二種用法:

substr(string A,int start,int len)和 substring(string A,int start,int len),用法一樣

功效:返回字元串A從下標start位置開始,長度為len的字元串

3、get_json_object(form_data,'$.學生姓名') as student_name

json_tuple 函數的作用:用來解析json字元串中的多個欄位

4、split(full_name, '\\.') [5] AS zq;  取的是數組里的第六個

日期(時間)函數:

1、to_date(event_time) 返回日期部分

2、date_sub:返回當前日期的相對時間

當前日期:select curdate() 

當前日期前一天:select  date_sub(curdate(),interval 1 day)

當前日期後一天:select date_sub(curdate(),interval -1 day)

date_sub(from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss'), 14)  將現在的時間總秒數轉為標准格式時間,返回14天之前的時間

時間戳>>>>日期:

from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss') 將現在的時間總秒數轉為標准格式時間

from_unixtime(get_json_object(get_json_object(form_data,'$.挽單時間'),'$.$date')/1000) as retain_time

unix_timestamp('2019-08-15 16:40:00','yyyy-MM-dd HH:mm:ss')  --1565858400

日期>>>>時間戳:unix_timestamp()

date_format:yyyy-MM-dd HH:mm:ss 時間轉格式化時間

select date_format('2019-10-07 13:24:20', 'yyyyMMdd000000')-- 20191007000000select date_format('2019-10-07', 'yyyyMMdd000000')-- 20191007000000

1.日期比較函數: datediff語法: datediff(string enddate,string startdate) 

返回值: int 

說明: 返回結束日期減去開始日期的天數。 

舉例:  hive> select datediff('2016-12-30','2016-12-29');  1

2.日期增加函數: date_add語法: date_add(string startdate, intdays) 

返回值: string 

說明: 返回開始日期startdate增加days天後的日期。 

舉例:  hive>select date_add('2016-12-29',10);  2017-01-08

3.日期減少函數: date_sub語法: date_sub (string startdate,int days) 

返回值: string 

說明: 返回開始日期startdate減少days天後的日期。 

舉例:  hive>select date_sub('2016-12-29',10);  2016-12-19

4.查詢近30天的數據

select * from table where datediff(current_timestamp,create_time)<=30;

create_time 為table里的欄位,current_timestamp 返回當前時間 2018-06-01 11:00:00

3、trunc()函數的用法:當前日期的各種第一天,或者對數字進行不四捨五入的截取

日期:

1.select trunc(sysdate) from al  --2011-3-18  今天的日期為2011-3-18

2.select trunc(sysdate, 'mm')   from   al  --2011-3-1    返回當月第一天.

上月1號    trunc(add_months(current_date(),-1),'MM')

3.select trunc(sysdate,'yy') from al  --2011-1-1       返回當年第一天

4.select trunc(sysdate,'dd') from al  --2011-3-18    返回當前年月日

5.select trunc(sysdate,'yyyy') from al  --2011-1-1   返回當年第一天

6.select trunc(sysdate,'d') from al  --2011-3-13 (星期天)返回當前星期的第一天

7.select trunc(sysdate, 'hh') from al   --2011-3-18 14:00:00   當前時間為14:41  

8.select trunc(sysdate, 'mi') from al  --2011-3-18 14:41:00   TRUNC()函數沒有秒的精確

數字:TRUNC(number,num_digits) Number 需要截尾取整的數字。Num_digits 的默認值為 0。TRUNC()函數截取時不進行四捨五入

11.select trunc(123.458,1) from al --123.4

12.select trunc(123.458,-1) from al --120

4、round():四捨五入:

select round(1.455, 2)  #結果是:1.46,即四捨五入到十分位,也就是保留兩位小數

select round(1.5)  #默認四捨五入到個位,結果是:2

select round(255, -1)  #結果是:260,即四捨五入到十位,此時個位是5會進位

floor():地板數

ceil()天花板數

5、

6.日期轉年函數: year語法:   year(string date) 

返回值: int

說明: 返回日期中的年。

舉例:

hive>   select year('2011-12-08 10:03:01') from al;

2011

hive>   select year('2012-12-08') fromal;

2012

7.日期轉月函數: month語法: month   (string date) 

返回值: int

說明: 返回日期中的月份。

舉例:

hive>   select month('2011-12-08 10:03:01') from al;

12

hive>   select month('2011-08-08') fromal;

8

8.日期轉天函數: day語法: day   (string date) 

返回值: int

說明: 返回日期中的天。

舉例:

hive>   select day('2011-12-08 10:03:01') from al;

8

hive>   select day('2011-12-24') fromal;

24

9.日期轉小時函數: hour語法: hour   (string date) 

返回值: int

說明: 返回日期中的小時。

舉例:

hive>   select hour('2011-12-08 10:03:01') from al;

10

10.日期轉分鍾函數: minute語法: minute   (string date) 

返回值: int

說明: 返回日期中的分鍾。

舉例:

hive>   select minute('2011-12-08 10:03:01') from al;

3

11.日期轉秒函數: second語法: second   (string date) 

返回值: int

說明: 返回日期中的秒。

舉例:

hive>   select second('2011-12-08 10:03:01') from al;

1

12.日期轉周函數: weekofyear語法:   weekofyear (string date) 

返回值: int

說明: 返回日期在當前的周數。

舉例:

hive>   select weekofyear('2011-12-08 10:03:01') from al;

49

查看hive表在hdfs中的位置:show create table 表名;

在hive中hive2hive,hive2hdfs:

HDFS、本地、hive -----> Hive:使用 insert into | overwrite、loaddata local inpath "" into table student;

Hive ----> Hdfs、本地:使用:insert overwrite | local

網站訪問量統計:

uv:每用戶訪問次數

ip:每ip(可能很多人)訪問次數

PV:是指頁面的瀏覽次數

VV:是指你訪問網站的次數

sql:

基本函數:

count、max、min、sum、avg、like、rlike('2%'、'_2%'、%2%'、'[2]')(java正則)

and、or、not、in   

where、group by、having、{ join on 、full join}  、order by(desc降序)

sort by需要與distribut by集合結合使用:

hive (default)> set maprece.job.reces=3;  //先設置rece的數量 

insert overwrite local directory '/opt/mole/datas/distribute-by'

row format delimited fields terminated by '\t'

先按照部門編號分區,再按照員工編號降序排序。

select * from emp distribute by deptno sort by empno desc;

外部表  create external table if not exists dept

分區表:create table dept_partition ( deptno int, dname string, loc string )  partitioned by ( month string )

load data local inpath '/opt/mole/datas/dept.txt' into table default.dept_partition partition(month='201809'); 

 alter table dept_partition add/drop partition(month='201805') ,partition(month='201804');

多分區聯合查詢:union

select * from dept_partition2 where month='201809' and day='10';

show partitions dept_partition;

desc formatted dept_partition;

二級分區表:create table dept_partition2 ( deptno int, dname string, loc string ) partitioned by (month string, day string) row format delimited fields terminated by '\t';

分桶抽樣查詢:分區針對的是數據的存儲路徑;分桶針對的是數據文件

create table stu_buck(id int, name string) clustered by(id) into 4 bucketsrow format delimited fields terminated by '\t';

設置開啟分桶與rece為1:

set hive.enforce.bucketing=true;

set maprece.job.reces=-1;

分桶抽樣:select * from stu_bucktablesample(bucket x out of y on id);

抽取,桶數/y,x是從哪個桶開始抽取,y越大 抽樣數越少,y與抽樣數成反比,x必須小於y

給空欄位賦值:

如果員工的comm為NULL,則用-1代替或用其他欄位代替  :select nvl(comm,-1) from emp;

case when:如何符合記為1,用於統計、分組統計

select dept_id, sum(case sex when '男' then 1 else 0 end) man , sum(case sex when '女' then 1 else 0 end) woman from emp_sex group by dept_id;

用於組合歸類匯總(行轉列):UDAF:多轉一

concat:拼接查詢結果

collect_set(col):去重匯總,產生array類型欄位,類似於distinct

select t.base, concat_ws('|',collect_set(t.name))   from (select concat_ws(',',xingzuo,blood_type) base,name  from person_info) t group by t.base;

解釋:先第一次查詢得到一張沒有按照(星座血型)分組的表,然後分組,使用collect_set將名字組合成數組,然後使用concat將數組變成字元串

用於拆分數據:(列轉行):UDTF:一轉多

explode(col):將hive一列中復雜的array或者map結構拆分成多行。

lateral view  側面顯示:用於和UDTF一對多函數搭配使用

用法:lateral view udtf(expression) tablealias as cate

cate:炸開之後的列別名

temptable :臨時表表名

解釋:用於和split, explode等UDTF一起使用,它能夠將一列數據拆成多行數據,在此基礎上可以對拆分後的數據進行聚合。

開窗函數:

Row_Number,Rank,Dense_Rank  over:針對統計查詢使用

Row_Number:返回從1開始的序列

Rank:生成分組中的排名序號,會在名詞s中留下空位。3 3 5

dense_rank:生成分組中的排名序號,不會在名詞中留下空位。3 3 4

over:主要是分組排序,搭配窗口函數使用

結果:

SUM、AVG、MIN、MAX、count

preceding:往前

following:往後

current row:當前行

unbounded:unbounded preceding 從前面的起點, unbounded following:到後面的終點

sum:直接使用sum是總的求和,結合over使用可統計至每一行的結果、總的結果、當前行+之前多少行/之後多少行、當前行到往後所有行的求和。

over(rowsbetween 3/current )  當前行到往後所有行的求和

ntile:分片,結合over使用,可以給數據分片,返回分片號

使用場景:統計出排名前百分之或n分之一的數據。

lead,lag,FIRST_VALUE,LAST_VALUE

lag與lead函數可以返回上下行的數據

lead(col,n,dafault) 用於統計窗口內往下第n行值

第一個參數為列名,第二個參數為往下第n行(可選,默認為1),第三個參數為默認值(當往下第n行為NULL時候,取默認值,如不指定,則為NULL)

LAG(col,n,DEFAULT) 用於統計窗口內往上第n行值

第一個參數為列名,第二個參數為往上第n行(可選,默認為1),第三個參數為默認值(當往上第n行為NULL時候,取默認值,如不指定,則為NULL)

使用場景:通常用於統計某用戶在某個網頁上的停留時間

FIRST_VALUE:取分組內排序後,截止到當前行,第一個值

LAST_VALUE:取分組內排序後,截止到當前行,最後一個值

范圍內求和: https://blog.csdn.net/happyrocking/article/details/105369558

cume_dist,percent_rank

–CUME_DIST :小於等於當前值的 行數 / 分組內總行數

–比如,統計小於等於當前薪水的人數,占總人數的比例

percent_rank:分組內當前行的RANK值-1/分組內總行數-1

總結:

在Spark中使用spark sql與hql一致,也可以直接使用sparkAPI實現。

HiveSql窗口函數主要應用於求TopN,分組排序TopN、TopN求和,前多少名前百分之幾。

與Flink窗口函數不同。

Flink中的窗口是用於將無線數據流切分為有限塊處理的手段。

window分類:

CountWindow:按照指定的數據條數生成一個 Window,與時間無關。

TimeWindow:按照時間生成 Window。

1. 滾動窗口(Tumbling Windows):時間對齊,窗口長度固定,不重疊::常用於時間段內的聚合計算

2.滑動窗口(Sliding Windows):時間對齊,窗口長度固定,可以有重疊::適用於一段時間內的統計(某介面最近 5min 的失敗率來報警)

3. 會話窗口(Session Windows)無時間對齊,無長度,不重疊::設置session間隔,超過時間間隔則窗口關閉。