index :通過有序索引順序掃描直接返回有序數據,不需要額外的排序,操作效率較高。
filesort:通過對返回數據進行排序,filesort 並不代表通過磁盤文件排序,而是說明進行了一個排序操作,至於排序操作是否使用了磁盤文件或臨時表等,則取決於MySQL服務器對排序參數的設置和需要排序數據的大小。
一般而言,filesort是通過相應的排序算法,將所取得的數據在sort_buffer_size系統變量設置的內存排序區中進行排序,如果內存裝載不下,它就會將磁盤上的數據進行分塊,再對各個數據塊進行排序,然后將各個塊合並成有序的結果集。
sort_buffer_size設置的排序區是每個線程獨占的,所以同一時刻,MySQL中存在多個sort buffer排序區。
優化:盡量減少額外排序,通過索引直接返回有序的數據。where 條件和order by 使用了相同的索引,並且order by 的順序和索引順序相同,並且order by 的字段都是升序或者降序,否則肯定需要額外的排序操作,這樣就會出現 filesort。
以下SQL可以使用索引:
select * from tablename order by key_part1,key_part2,....;
select * from tablename where key_part1=1 order by key_part1 desc,key_part2 desc;
select * from tablename order by key_part1 desc,key_part2 desc;
以下SQL不可以使用索引:
select * from tablename order by key_part1 desc,key_part2 asc; ----order by 的字段混合asc,desc
select * from tablename where key2=constant order by key1; ----用於查詢的關鍵字與order by 中所使用的不相同
select * from tablename order by key1,key2; ----對不同的關鍵字使用order by
對於Filesort,MySQL有兩種排序算法 :
一次掃描算法和兩次掃描算法,通過比較系統變量max_length_for_sort_data的大小和query語句總字段的大小來判斷使用哪種排序算法。
適當增加 max_length_for_sort_data的值,適當增加sort_buffer_size排序區,盡量使用具體的字段而不是select * 選擇所有字段。
在CPU和IO之間平衡。