Hive里的With關鍵字用法(調優)


with...as...也叫做子查詢部分,語句允許hive定義一個sql片段,供整個sql使用

簡介
with...as...需要定義一個sql片段,會將這個片段產生的結果集保存在內存中,
后續的sql均可以訪問這個結果集和,作用與視圖或臨時表類似.

語法限制
with...as...必須和其他sql一起使用(可以定義一個with但在后續語句中不使用他)
with...as...是一次性的
with...as...的完整格式是這樣的

-- with table_name as(子查詢語句) 其他sql 
with temp as (
    select * from xxx
)
select * from temp;

只定義不實用

with temp as (
    select * from xxx
)
select * from othertable;

同級的多個temp之間用,分割with只需要一次,as后的子句必須用(),

with temp1 as (
    select * from xxx
),temp2 as (
    select * from xxx
)
select * from temp1,temp2;

with...as...當然是可以嵌套的,此處舉一個簡單例子

with temp2 as (
    with temp1 as (
        select * from xxx
    )
    select * from temp1
)
select * from temp2;

with...as...只能在一條sql中使用

with temp1 as (
    select * from xxx
)
select * from temp1;
select xxx from temp1; -- error! no table named temp1;

語句的優點
提高代碼可讀性(結構清晰)
簡化sql,優化執行速度(with子句只需要執行一次)
栗子
現有 city 表,結構如下:

city_number city_name province
010 北京 北京
021 上海 上海
025 南京 江蘇
0512 昆山 江蘇
0531 濟南 山東
0533 淄博 山東
然后分別有商品表good

city_number good_name
010 A
021 B
現在需要分別統計這上海商品,一般sql如下:

select * from `good`  where city_number in (select city_number from city where city_name = "上海");

除了子查詢,上述的的例子還可以用join來實現,

如果用with...as...語句實現,如下

with tmp_shanghai as(
    select city_number from city where city_name = "上海"
)
select * from `good` where tmp_shanghai in (select * from tmp_shanghai) 

看起來使用 with...as... 語句反而更復雜一點,但如果tmp_shanghai要被多次使用的使用,就很有必要

來看一個實際的例子,有一張操作表event主要字段如下:

date event_key
20190530 Delete
20190530 Put
20190530 Get
20190530 Get
20190601 Set
......

現在要求一條sql統計出Get與Set 操作的數量,先使用子查詢實現

select (
    select count(*) from event where event_key = "Get"
) as get_num,(
    select count(*) from event where event_key = "Set"
) as set_num

如果再增加其他項的統計呢,是否每一個均需要增加一個對event表進行掃描的自查詢

使用 with...as...

with temp as(
    select * from event where event_key = "Get" or event_key = "Set"
)
--如果 需要對查詢出來的數據進行操作,要寫在select上面,比如insert
insert into table table_name partititon(dt='2020-1-1')
select 
    sum(case when event_key = "Get" then 1 else 0 end) as get_num,
    sum(case when event_key = "Set" then 1 else 0 end) as Set_num
from temp

閱讀性是否比之前有所提高?此外,這條語句只對event表進行了一次掃描,將符合條件的數據存入temp中供后續計算,
在event表數據集非常大的情況下,性能將比子查詢的方式優秀很多

轉載自:https://blog.csdn.net/qq_44671288/article/details/108245394


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM