hive嚴格模式


說真的,這個模式在我做sql開發的歲月里,從未用到過。用的都是動態分區非嚴格模式。

我的好友東岳同學在車上問我。確實問到了我 。體現出了我基本功不扎實的情況。

1.what is Hive嚴格模式

Hive提供了一個嚴格模式,可以防止用戶執行那些可能產生意向不到的不好的效果的查詢。說通俗一點就是這種模式可以阻止某些查詢的執行。通過如下語句設置嚴格模式:

hive> set hive.mapred.mode=strict;

2.why and how

設置為嚴格模式后,可以禁止3種類型的查詢:

(1):帶有分區的表的查詢

如果在一個分區表執行hive,除非where語句中包含分區字段過濾條件來顯示數據范圍,否則不允許執行。換句話說就是在嚴格模式下不允許用戶掃描所有的分區。

進行這個限制的原因是,通常分區表都擁有非常大的數據集,而且數據增加迅速。如果不進行分區限制的查詢會消耗巨大的資源來處理,如下不帶分區的查詢語句:

hive> SELECT DISTINCT(planner_id) FROM fracture_ins WHERE planner_id=5;

執行后會出現如下錯誤:

FAILED: Error in semantic analysis: No Partition Predicate Found for Alias "fracture_ins" Table "fracture_ins

解決方案是在where中增加分區條件:

hive> SELECT DISTINCT(planner_id) FROM fracture_ins
       > WHERE planner_id=5 AND hit_date=20120101;

 

(2)帶有orderby的查詢 
對於使用了orderby的查詢,要求必須有limit語句。因為orderby為了執行排序過程會講所有的結果分發到同一個reducer中 
進行處理,強烈要求用戶增加這個limit語句可以防止reducer額外執行很長一段時間:

hive> SELECT * FROM fracture_ins WHERE hit_date>2012 ORDER BY planner_id;

出現如下錯誤:

FAILED: Error in semantic analysis: line 1:56 In strict mode,limit must be specified if ORDER BY is present planner_id

解決方案就是增加一個limit關鍵字:

hive> SELECT * FROM fracture_ins WHERE hit_date>2012 ORDER BY planner_id LIMIT 100000;

(3):限制笛卡爾積的查詢

對關系型數據庫非常了解的用戶可能期望在執行join查詢的時候不適用on語句而是使用where語句,這樣關系型數據庫的執行優化器就可以高效的將where語句轉換成那個on語句了。不幸的是,Hive並不支持這樣的優化,因為如果表非常大的話,就會出現不可控的情況,如下是不帶on的語句:

hive> SELECT * FROM fracture_act JOIN fracture_ads WHERE fracture_act.planner_id = fracture_ads.planner_id;

出現如下錯誤:

FAILED: Error in semantic analysis: In strict mode, cartesian product is not allowed. If you really want to perform the operation, +set hive.mapred.mode=nonstrict+

=======》我感覺整個博客園都存在不加思考的抄襲的現象。要不然就是改一改表名,裝作成自己的。連最基礎的概念什么是笛卡爾積都不知道

 

這才是真正的笛卡爾積,上面根本不會報錯。

hive> SELECT * FROM fracture_act JOIN fracture_ads WHERE 1= 1;

 或者是

hive> SELECT * FROM fracture_act JOIN fracture_ads;

 

解決方案就是加上on語句:

hive> SELECT * FROM fracture_act JOIN fracture_ads ON (fracture_act.planner_id = fracture_ads.planner_id);

 或者是加上where條件

hive> SELECT * FROM fracture_act JOIN fracture_ads WHERE fracture_act.planner_id = fracture_ads.planner_id;

不過on性能更好一些。


免責聲明!

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



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