group by流程是怎麼樣的
注意點:
select id%10 as m, count(*) as c from t1 group by m;
- group by是用于對資料進行分組,我們排序用到了sort_buff,join用到了join_buff,group by就會用到
。join_buffer 是無序數組,sort_buffer 是有序數組,臨時表是二維表結構;内部臨時表
- 多使用explain分析sql語句,在 Extra 字段裡面,我們可以看到三個資訊:
- Using index,表示這個語句使用了覆寫索引,選擇了索引 a,不需要回表;
- Using temporary,表示使用了臨時表;
- Using filesort,表示需要排序。
- 使用内部臨時表預設都是引擎,union和人工建立臨時表都是使用到臨時表。
- 如果你的需求并不需要對結果進行排序,那你可以在 SQL 語句末尾增加 order by null。
- 記憶體臨時表也會有大小限制,如果臨時表空間放不下資料,也會使用磁盤空間作為臨時表的空間
- group by 的字段盡可能也需要索引,有序的資料, 在執行就可能不需要排序和臨時表了。
- group by優化還可以不使用臨時表,比如大量資料group by,臨時表空間肯定不夠,你可以在 group by 語句中加入 SQL_BIG_RESULT 這個提示(hint),就可以告訴優化器:這個語句涉及的資料量很大,請直接用磁盤臨時表。這種情況下在explain就不會有使用了臨時表的關鍵字了。直接排序使資料有序。有序資料就直接使用第6點性能優化。
流程如下:
- 建立記憶體臨時表,表裡有兩個字段 m 和 c,主鍵是 m;
- 掃描表 t1 的索引 a,依次取出葉子節點上的 id 值,計算 id%10 的結果,記為 x;
- 如果臨時表中沒有主鍵為 x 的行,就插入一個記錄 (x,1);如果表中有主鍵為 x 的行,就将 x 這一行的 c 值加 1;
- 周遊完成後,再根據字段 m 做排序,得到結果集傳回給用戶端。