SQL效能優化
SQL效能優化
目錄前言
SQL優化是一個長期的過程。很多優化原則並不是固定不變的,應根據實際業務要求進行。管理員應經常檢查TOP SQL,及時與開發人員進行溝通,根據實際情況制定優化策略。原則上講,SQL優化是應用開發人員的事。
第1條
SQL語句多表關聯時,應使用別名。相關欄位通過別名進行應用。使用別名可以減少優化器查詢物件關聯的複雜度,降低解析代價。
第2條
對於關鍵SQL語句,儘量簡化,不要包含太多的層次,避免執行計劃錯誤的可能,原則上不能超過5層;
第3條
應儘可能避免order by,group by,distinct等引起不必要排序的操作。
第4條
應儘量使檢索條件的兩側型別一致,避免where查詢條件做隱型轉換時後出現混亂,導致產生錯誤的執行計劃。
第5條
注意like的使用方法,變數%要注意查詢範圍, %在開頭或者末尾,選擇性最好。
第6條
防止group by的key分佈不均勻,在SQL執行前設定防傾斜的引數:
set hive.groupby.skewindata=true。
有資料傾斜的時候進行負載均衡,當選項設定為true,生成的查詢計劃會有兩個MR Job。第一個MR Job中,Map 的輸出結果集合會隨機分佈到Reduce中,每個Reduce做部分聚合操作,並輸出結果,這樣處理的結果是相同的Group By Key有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MR Job再根據預處理的資料結果按照Key分佈到Reduce中(這個過程可以保證相同的Key被分佈到同一個Reduce中),最後完成最終的聚合操作。
第7條
join時key分佈不均勻會導致資料傾斜,可以有兩種解決方案:
1.如果join的兩邊有一個是小表,可以把join改成map join來處理。
2.傾斜的key用單獨的邏輯來處理,例如經常發生兩邊的key裡有大量null資料導致了傾斜。則需要在join前先過濾掉null的資料或者補上隨機數,然後再進行join。
如:
select * from log a left outer join users b on case when a.user_id is null then concat('hive',rand()) else a.user_id end = b.user_id;
如果key為null的資料不需要使用建議先過濾掉key值為null的資料,當然大部分情況下,可能傾斜的值不是null,而是有意義的資料,那麼這時候就需要把這類資料單獨拎出來單獨處理,分而治之。
第8條
count distinct時也容易發生資料傾斜,常見於固定的特殊值較多的場景。count distinct時,將值為空的情況單獨處理,如果只是計算count distinct,可以不用處理,直接過濾,在最後結果中加1。如果還有其他計算,需要進行group by,可以先將值為空的記錄單獨處理,再和其他計算結果進行union。
第9條
當一個大表和一個或多個小表做JOIN時,要求使用MAPJOIN,效能比普通的JOIN要快很多。 另外,MAPJOIN 還能解決資料傾斜的問題。
-
LEFT OUTER JOIN的左表必須是大表
-
RIGHT OUTER JOIN的右表必須是大表
-
FULL OUTER JOIN不能使用MAPJOIN
-
MAPJOIN支援小表為子查詢
-
使用MAPJOIN時需要引用小表或是子查詢時,需要引用別名
資料傾斜
資料傾斜原因:
1.key分佈不均勻
2.業務資料本身的特性
3.建表時考慮不周
4.某些Sql語句本身就有資料傾斜
(目的是如何將資料均勻的分配到各個reduce中)
處理資料傾斜主要的方法:
1.map join
2.map端combine
3.給key賦字首進行擴容
4.避免使用造成單reduce的函式