1. 程式人生 > >MYSQL優化-之GROUP BY

MYSQL優化-之GROUP BY

plain 2種 borde ext emp 例如 般的 查詢條件 屬性。

轉載: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 順序.問題.

  1. 用於搜索記錄的索引鍵和做 GROUP BY 的不是同一個:

其實意思是。Where 條件和GROUP BY 字段得是一個索引裏面的。

這個就不舉例了。

我相信通過這篇文章大家也了解了GROUP BY 的索引應用了吧!

其實我們多嘗試,多分析下就可以了。

如有有疑問,請大家多多指出,我將會修正。

MYSQL優化-之GROUP BY