MYSQL優化-之GROUP BY
轉載:https://my.oschina.net/heguangdong/blog/38567
在web應用中,提倡sql簡單,避免復雜度。所以在我們公司的應用中看不到jon,子查詢等語句的存在,所以間接GROUP BY 與 索引的使用占據大多數,其實很多技巧,別人都是總結過的,仔細分析,仔細學習別人的經驗才是正道.而不可浮躁,憑經驗主義.
滿足GROUP BY子句的最一般的方法是掃描整個表並創建一個新的臨時表,表中每個組的所有行應為連續的,然後使用該臨時表來找到組並應用累積函數(如 果有)。(用通俗的語言就是,建立一個臨時表。然後利用mysql內部算法。算出來結果)
在某些情況中,MySQL能夠做得更好,通過索引訪問而不用創建臨時表。 (其實就是因為臨時表的東西,我們才應該優化。)
一般GROUP BY 優化分為2種優化方式:
1。松散索引掃描
2,。緊湊索引掃描
何為松散索引掃描:
其實就是:
通過該訪問方法,MySQL使用某些關鍵字排序的索引類型的 屬性。該屬性允許使用 索引中的查找組而不需要考慮滿足所有WHERE條件的索引中的所有關鍵字。既然該訪問方法只考慮索引中的關鍵字的一小 部分,它被稱為松散索引列表。(官方語言就是精辟)
例如:
explain select TeamID from competeinfo where TeamID >10 group by TeamID
id |
select_type |
table |
type |
possible_keys |
key |
key_len |
ref |
rows |
Extra |
1 |
SIMPLE |
competeinfo |
range |
TeamID |
TeamID |
4 |
NULL |
26 |
Using where; Using index for group-by |
這裏的explain 代表查看索引應用情況。我簡單介紹一下.
id->SELECT識別符。這是SELECT的查詢序列號。
select_type -> SELECT類型, SIMPLE代表比較簡單的查詢。(還包括union,primary等,具體去查下手冊)
table 代表所引用的表。
type->聯接類型 。可以說索引應用狀況。這裏range只檢索給定範圍的行,使用一個索引來選擇行 。大多數我們將對索引用到 > < 等之類的符號。(還包括其他的聯接類型,all代表掃描整個表。至於其他關鍵字。還查手冊吧)
possible_keys->MySQL能使用哪個索引在該表中找到行(這裏不是真正應用到)
key ->MYSQL實際應用到的索引。
key_len->索引長度
ref使用哪個列或常數與key一起從表中選擇行。
rows-》影響多少行
Extra-》一些索引應用狀況信息。這裏的Using index for group-by 表示松散索引。
如果這裏出現useing tempoary useingfilesort。這個是比較嚴重的。這證明你的索引,沒有用用到。解決方式:改索引吧。
言歸正傳。這裏select TeamID from competeinfo where TeamID >10 group by TeamID。就是通過TeamID 來查找組。完成group by .這個也是一種方式。
但是大家註意。查詢字段必須和後面GROUP BY 一致.
第二種優化方式,也是最常用的。緊湊索引掃描。
何為緊湊索引掃描:索引掃描或一個範圍索引掃描,取決於查詢條件。
其實啊就是聯合索引的應用。
explain select TeamID from competeinfo where TeamID >10 and CompeteID > 100020 group by CompeteID
這個表建立了。 CompeteID, TeamID的聯合索引。
id |
select_type |
table |
type |
possible_keys |
key |
key_len |
ref |
rows |
Extra |
1 |
SIMPLE |
competeinfo |
range |
CompeteID,TeamID |
CompeteID |
4 |
NULL |
22 |
Using where; Using index |
大家已經看到了。這裏我們會發現。可能應用索引有2個。實際應用到索引名為CompeteID.返回應用信息也是Using where; Using index。應用到索引。
下面我說下:哪些情況應用不到。
1. 對不同的索引鍵做 GROUP BY
SELECT * FROM a1 group by key1, key2;
2. 在非連續的索引鍵部分上做 group by
SELECT * FROM t1 WHERE key2=constant group by key_part2;
非連續索引:上面的索引CompeteID。他是由CompeteID, TeamID建立聯合索引。
explain select TeamID from competeinfo where TeamID >10 and CompeteID > 100020 group by TeamID
這樣的話。
id |
select_type |
table |
type |
possible_keys |
key |
key_len |
ref |
rows |
Extra |
1 |
SIMPLE |
competeinfo |
range |
CompeteID,TeamID |
CompeteID |
4 |
NULL |
22 |
Using where; Using index; Using temporary; Using filesort |
大家看見了。EXTRA的信息。這樣的話group by 沒用應用索引。影響效率。
所以一定註意到。GROUP BY 順序.問題.
-
用於搜索記錄的索引鍵和做 GROUP BY 的不是同一個:
其實意思是。Where 條件和GROUP BY 字段得是一個索引裏面的。
這個就不舉例了。
我相信通過這篇文章大家也了解了GROUP BY 的索引應用了吧!
其實我們多嘗試,多分析下就可以了。
如有有疑問,請大家多多指出,我將會修正。
MYSQL優化-之GROUP BY