mysql中group by實現方式有三種,松散索引,緊湊索引,臨時文件(文件排序)。
在網上看了相關的介紹,大部分介紹都比較晦澀難懂,這里說下我的理解。
在學習SQL優化時,我們都知道可以對group by進行優化的方式就是對group by引用的字段建立索引。當group by引用多個字段時,我們建立的相應的索引也應包含多個字段。
對group by操作優化的原理就是讓mysql利用索引,而避免進行建立臨時表,進而進行文件排序(group by的第三種實現方式)。
對於group by引用的多個字段,需滿足於所建立索引的最左前綴索引,否則進行group by操作時,無法利用索引。在利用索引時,group by可根據索引,即可對數據分組,此時完全不用去
訪問表的數據值(索引健對應的數據)。這種實現方式就是利用松散索引。
當group by引用的字段無法構成所建索引的最左前綴索引時,也就是說group by不能利用索引時。如何where語句(如果有的話)彌補了這種差距,比如:group by
引用的字段為(c2,c3),而索引為(c1,c2,c3)。此時如果where語句限定了c1=a(某一個值),那么此時mysql的執行過程為先根據where語句進行一次選擇,
對選出來的結果集,可以利用索引。這種方式,從整體上來說,group by並沒有利用索引,但是從過程來說,在選出的結果中利用了索引,這種方式就是緊湊索引。
這種方式,mysql的執行計划為using where,use index。而松散索引的執行計划為using index for group by。
如果mysql如論如何都不能利用索引時,此時mysql將讀取所有的數據建立臨時表,對文件進行排序,完成分組操作。
關於group的作用:
滿足於我們針對某些字段進行分組,然后在組內對多行數據進行處理(計算行數,計算max,min等等)這樣的需求。group by返回的數據是有序的。
如果我們對數據進行分組后,要輸出(select)其所有(多)行的數據,此時是無法實現的。根據版本的不同,可能會輸出第一行數據,可能會保錯。
相關鏈接 http://www.51testing.com/html/52/n-229952.html
