說真的,這個模式在我做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性能更好一些。