在web應用中,提倡sql簡單,避免複雜度。因此在咱們公司的應用中看不到jon,子查詢等語句的存在,因此間接GROUP BY 與 索引的使用佔據大多數,其實不少技巧,別人都是總結過的,仔細分析,仔細學習別人的經驗纔是正道.而不可浮躁,憑經驗主義.mysql
知足GROUP BY子句的最通常的方法是掃描整個表並建立一個新的臨時表,表中每一個組的全部行應爲連續的,而後使用該臨時表來找到組並應用累積函數(如 果有)。(用通俗的語言就是,創建一個臨時表。而後利用mysql內部算法。算出來結果)web
在某些狀況中,MySQL可以作得更好,經過索引訪問而不用建立臨時表。 (其實就是由於臨時表的東西,咱們才應該優化。)算法
通常GROUP BY 優化分爲2種優化方式:sql
1。鬆散索引掃描函數
2,。緊湊索引掃描學習
何爲鬆散索引掃描:優化
其實就是:spa
經過該訪問方法,MySQL使用某些關鍵字排序的索引類型的 屬性。該屬性容許使用 索引中的查找組而不須要考慮知足全部WHERE條件的索引中的全部關鍵字。既然該訪問方法只考慮索引中的關鍵字的一小 部分,它被稱爲鬆散索引列表。(官方語言就是精闢)orm
例如:排序
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 的索引應用了吧!
其實咱們多嘗試,多分析下就能夠了。
若有有疑問,請你們多多指出,我將會修正。