當使用order by對查詢結果進行排序時,MySQL會給每個線程分配一塊兒內存sort_buffer用於排序,在使用索引的情況下,整個的排序過程如下所述:
1. 初始化sort_buffer,確定放入結果中所需的字段;
2. 從索引中找到第一個滿足條件主鍵id;
3. 到主鍵id索引取出整行,取所需字段的值,存入sort_buffer中;
4. 從索引中取下一個記錄的主鍵id;
5. 重複步驟3、4直到索引中的值不滿足查詢條件爲止;
6. 對sort_buffer中的數據按照order by
的字段做快速排序;
7. 根據limit
語句按照排序結果取前n行返回給客戶端
其中第六步的排序,如果內存大小不夠則可能使用外部文件進行排序,緩存大小取決於sort_buffer_size
,如果使用外部文件,則採用類似於歸併排序的方式
當結果中需要的字段過多時 ,每行記錄比較大,可能會發生sort_buffer只能放下很少的記錄的情況,這時,需要的就是rowid排序。max_length_for_sort_data
用於控制緩存中每行能放下的數據大小,如果不能將所需字段都放進去,則會選擇order by
中需要的字段放進去,其餘的字段通過回表的方式,將第7步改爲:遍歷排序結果,取前n行,並按照id的值回到原表中取出所需字段返回給客戶端。也是由於這個回表過程的存在,所以MySQL會優先選擇第一種方法,儘量避免rowid方式,此外還可以通過覆蓋索引的方式再次減少回表過程。
MySQL實戰45講