可是從咱們的性能統計來看,全部的order by都是在內存中執行的,沒有在硬盤上執行。mysql
將排序改到應用層排序,整個性能立馬提升了不少。因而新的疑問就來了,難道mysql的排序性能這麼差嗎?算法
在http://forge.mysql.com/wiki/MySQL_Internals_Algorithms這裏發現了mysql的排序算法原理。sql
mysql的filesort算法有兩種,一種是最初的算法,在MySQL 4.1之前只有這種算法,另一種是改進的filesort算法,它出如今
MySQL 4.1之後(blob和text類型的字段不能採用這種改進算法)性能
最初的算法流程以下(簡單起見,假設數據小於等於sort_buffer_size,詳細能夠見上面的url):
1.讀取全部的知足條件的數據,只包含sort key和row pointer兩種數據
2.在buffer中執行qsort排序
3.排完序後,再根據row pointer去讀取相應的行數據url
從中能夠看出,每次排序都須要讀兩次表,而根據row pointer去讀表每每都是隨機離散讀的,全部其開銷很是大。排序
改進後的算法是:
1.讀取所須要的數據,包含sort key,row pointer和查詢所須要訪問的字段
2.根據sort key排序
3.按排序後的順序讀取數據,因爲sort_buffer_size中包含了所須要的字段,所以不須要再回表了,能夠直接返回結果給客戶端。內存
很明顯,這種改進的方法對sort_buffer_size的需求也大大增長,因此爲了防止性能降低,mysql增長了一個參數max_length_for_sort_data
當第一步中除了sort key之外的字段內容大於max_length_for_sort_data這個參數時,mysql將採用第一種排序算法。get
該參數默認爲1024個字節,而在咱們的離線消息中內容較大,因此mysql就採用了第一種排序算法,結果每次都要回表,因此性能不好。
將max_length_for_sort_data該參數調大,性能獲得了很大的提升。it
人人都說mysql簡單,其實在DB層面沒有簡單的事情,任何一個細小的東西里面都大有文章可講啊。
另外http://forge.mysql.com/wiki 這個wiki上面的內容很不錯,強烈推薦一下。原理