1. 程式人生 > >MySql中explain的時候出現using filesort,優化之(轉)

MySql中explain的時候出現using filesort,優化之(轉)

原文地址:http://blog.csdn.net/imzoer/article/details/8485680

在使用order by關鍵字的時候,如果待排序的內容不能由所使用的索引直接完成排序的話,那麼mysql有可能就要進行檔案排序。

【這個 filesort 並不是說通過磁碟檔案進行排序,而只是告訴我們進行了一個排序操作而已】。

當然,using filesort不一定引起mysql的效能問題。但是如果查詢次數非常多,那麼每次在mysql中進行排序,還是會有影響的。
此時,可以進行的優化:
1、修改邏輯,不在mysql中使用order by而是在應用中自己進行排序。
2、使用mysql索引,將待排序的內容放到索引中,直接利用索引的排序。

上面這個例子可以很好的說明問題。在b表中,由於最初沒有(a,b)索引,所以要進行filesort。新增索引之後,問題解決。

----------------------------------------------------------

filesort是通過相應的排序演算法,將取得的資料在記憶體中進行排序:。
MySQL需要將資料在記憶體中進行排序,所使用的記憶體區域也就是我們通過sort_buffer_size 系統變數所設定的排序區。
這個排序區是每個Thread 獨享的,所以說可能在同一時刻在MySQL 中可能存在多個 sort buffer 記憶體區域。
在MySQL中filesort 的實現演算法實際上是有兩種:
雙路排序

:是首先根據相應的條件取出相應的排序欄位和可以直接定位行資料的行指標資訊,然後在sort buffer 中進行排序。
單路排序:是一次性取出滿足條件行的所有欄位,然後在sort buffer中進行排序。
在MySQL4.1版本之前只有第一種排序演算法雙路排序,第二種演算法是從MySQL4.1開始的改進演算法,主要目的是為了減少第一次演算法中需要兩次訪問表資料的 IO 操作,將兩次變成了一次,但相應也會耗用更多的sortbuffer 空間。當然,MySQL4.1開始的以後所有版本同時也支援第一種演算法。
MySQL主要通過比較我們所設定的系統引數 max_length_for_sort_data的大小和Query 語句所取出的欄位型別大小總和來判定需要使用哪一種排序演算法。如果 max_length_for_sort_data更大,則使用第二種優化後的演算法,反之使用第一種演算法。所以如果希望 ORDER BY 操作的效率儘可能的高,一定要注意max_length_for_sort_data 引數的設定。如果filesort過程中,由於排序快取的大小不夠大,那麼就可能會導致;臨時表的使用。

max_length_for_sort_data的預設值是1024。

---------------------------------------

mysql在使用雙路排序的時候,需要根據排好序的key,第二次去讀取真正要返回的資料的。這樣就會用到read_rnd_buffer_size這個引數定義的緩衝區。將讀取的資料放到這個緩衝區中。

隨機讀取資料緩衝區使用記憶體(read_rnd_buffer_size):和順序讀取相對應,當 MySQL 進行非順序讀取(隨機讀取)資料塊的時候,會利用這個緩衝區暫存讀取的資料。如根據索引資訊讀取表資料,根據排序後的結果集與表進行Join等等。總的來說,就是當資料塊的讀取需要滿足一定的順序的情況下,MySQL 就需要產生隨機讀取,進而使用到 read_rnd_buffer_size 引數所設定的記憶體緩衝區。
引數:read_rnd_buffer_size,預設8MB。

順便說下順序讀取緩衝read_buffer_size

順序讀取資料緩衝區使用記憶體(read_buffer_size):這部分記憶體主要用於當需要順序讀取資料的時候,如無法使用索引的情況下的全表掃描,全索引掃描等。在這種時候,MySQL 按照資料的儲存順序依次讀取資料塊,每次讀取的資料塊首先會暫存在read_buffer_size中,當buffer 空間被寫滿或者全部資料讀取結束後,再將buffer中的資料返回給上層呼叫者,以提高效率。
引數:read_buffer_size,預設2MB

------------------------------------------------------------------------------------------

再說下using temporary。【待續】