在執行計划中,可能經常看到有Extra列有filesort,這就是使用了文件排序,這當然是不好的,應該優化,但是,了解一下他排序的原理也許很有幫助,下面看一下filesort的過程:
1、根據表的索引或者全表掃描,讀取所有滿足條件的記錄。
2、對與每一行,存儲一對值到緩沖區(排序列,行記錄指針),一個是排序的索引列的值,即order by用到的列值,和指向該行數據的行指針,緩沖區的大小為sort_buffer_size大小。
3、當緩沖區滿后,運行一個快速排序(qsort)來將緩沖區中數據排序,並將排序完的數據存儲到一個臨時文件,並保存一個存儲塊的指針,當然如果緩沖區不滿,則不會重建臨時文件了。
4、重復以上步驟,直到將所有行讀完,並建立相應的有序的臨時文件。
5、對塊級進行排序,這個類似與歸並排序算法,只通過兩個臨時文件的指針來不斷交換數據,最終達到兩個文件,都是有序的。
6、重復5直到所有的數據都排序完畢。
7、采取順序讀的方式,將每行數據讀入內存,並取出數據傳到客戶端,這里讀取數據時並不是一行一行讀,讀如緩存大小由read_rnd_buffer_size來指定。
這就是filesort的過程,采取的方法為:快速排序 + 歸並排序,但有一個問題,就是,一行數據會被讀兩次,第一次是where條件過濾時,第二個是排完序后還得用行指針去讀一次,一個優化的方法是,直接讀入數據,排序的時候也根據 這個排序,排序完成后,就直接發送到客戶端了,過程如下:
1、讀取滿足條件的記錄
2、對於每一行,記錄排序的key和數據行指針,並且把要查詢的列也讀出來
3、根據索引key排序
4、讀取排序完成的文件,並直接根據數據位置讀取數據返回客戶端,而不是去訪問表
這也有一個問題:當獲取的列很多的時候,排序起來就很占空間,因此,max_length_for_sort_data變量就決定了是否能使用這個排序算法
建議:
1、對於使用filesort的慢查詢,可以改小一些max_length_for_sort_data來使用第一個方法
2、對於想要加快order by 的順序,有以下一些策略:
a、增加sort_buffer_size的大小,如果大量的查詢較小的話,這個很好,就緩存中就搞定了
b、增加read_rnd_buffer_size大小,可以一次性多讀到內存中
c、列的長度盡量小些
d、改變tmpdir,使其指向多個物理盤(不是分區)的目錄,這將機會循環使用做為臨時文件區
---------------------
原文:https://blog.csdn.net/xiaobing_blog/article/details/17152777