InnoDB
引擎有兩種排序方式
- 對返回的數據進行排序,
Explain
的Extra
列顯示using filesort
,所有不是通過索引直接返回排序結果的排序都稱爲Filesort
- 通過有序索引順序掃描直接返回有序數據,
Explain
的Extra
列顯示using index
MySQL
優化排序的思路:儘量減少額外的排序,或者通過有序索引直接返回有序數據。通常情況下,where
條件和order by
使用相同的索引,並且order by
後面的索引要和索引定義的順序保持一致,而且要保證多字段排序都是正序或倒序,否則就會出現Filesort
。
Filesort
的兩種排序算法
-
兩次掃描算法
MySQL4.1
之前,默認使用這種方式。大致流程:首先根據條件取出排序字段和行指針信息,然後在排序區sort buffer
中排序,如果sort buffer
大小不夠,將排序結果放入temporary table
中,完成排序後,根據行指針回表查詢數據。這算法可能會有大量的IO
操作,效率低。 -
一次掃描算法
一次性將滿足條件的所有字段放入sort buffer
中排序,內存開銷大,但排序效率比兩次掃描要高。
注意區分加粗的字,排序字段和行指針信息 和 所有字段 這算是兩種算法的核心。
Filesort 無法避免時的處理方式
MySQL
通過比較系統變量max_length_for_sort_data
的大小和Query
取出的字段總大小來判斷用哪種算法排序,如果max_length_for_sort_data
足以放下所有字段,那麼使用一次掃描算法。我們可以適當增大max_length_for_sort_data
和sort_buffer_size
系統變量擴大排序區的大小,提高排序效率。
查看大小
show variables like 'max_length_for_sort_data';
show variables like 'sort_buffer_size';
設置當前連接的大小
set max_length_for_sort_data = 2048;
set sort_buffer_size = 2097152;
設置全局大小
set global max_length_for_sort_data = 2048;
set global sort_buffer_size = 2097152;