天天看點

group by流程是怎麼樣的

group by流程是怎麼樣的

注意點:

select id%10 as m, count(*) as c from t1 group by m;

  1. group by是用于對資料進行分組,我們排序用到了sort_buff,join用到了join_buff,group by就會用到

    内部臨時表

    。join_buffer 是無序數組,sort_buffer 是有序數組,臨時表是二維表結構;
  2. 多使用explain分析sql語句,在 Extra 字段裡面,我們可以看到三個資訊:
  • Using index,表示這個語句使用了覆寫索引,選擇了索引 a,不需要回表;
  • Using temporary,表示使用了臨時表;
  • Using filesort,表示需要排序。
  1. 使用内部臨時表預設都是引擎,union和人工建立臨時表都是使用到臨時表。
  2. 如果你的需求并不需要對結果進行排序,那你可以在 SQL 語句末尾增加 order by null。
  3. 記憶體臨時表也會有大小限制,如果臨時表空間放不下資料,也會使用磁盤空間作為臨時表的空間
  4. group by 的字段盡可能也需要索引,有序的資料, 在執行就可能不需要排序和臨時表了。
  5. group by優化還可以不使用臨時表,比如大量資料group by,臨時表空間肯定不夠,你可以在 group by 語句中加入 SQL_BIG_RESULT 這個提示(hint),就可以告訴優化器:這個語句涉及的資料量很大,請直接用磁盤臨時表。這種情況下在explain就不會有使用了臨時表的關鍵字了。直接排序使資料有序。有序資料就直接使用第6點性能優化。

流程如下:

  1. 建立記憶體臨時表,表裡有兩個字段 m 和 c,主鍵是 m;
  2. 掃描表 t1 的索引 a,依次取出葉子節點上的 id 值,計算 id%10 的結果,記為 x;
  3. 如果臨時表中沒有主鍵為 x 的行,就插入一個記錄 (x,1);如果表中有主鍵為 x 的行,就将 x 這一行的 c 值加 1;
  4. 周遊完成後,再根據字段 m 做排序,得到結果集傳回給用戶端。