數據庫優化SQL優化之SELECT優化 ——filesort

在執行計劃中,可能經常看到有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,使其指向多個物理盤(不是分區)的目錄,這將機會循環使用做爲臨時文件區

             



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章