MySQL 效能優化之 order by 一

2021-08-09 11:37:06 字數 2221 閱讀 3223

前言

工作過程中,各種業務需求在訪問資料庫的時候要求有order by排序。有時候不必要的或者不合理的排序操作很可能導致資料庫系統崩潰。如何處理好order by排序呢?本文從原理以及優化層面介紹 order by 。

一 mysql中order by的原理

1 利用索引的有序性獲取有序資料

當查詢語句的 order by 條件和查詢的執行計畫中所利用的 index 的索引鍵(或前面幾個索引鍵)完全一致,且索引訪問方式為 rang,ref 或者 index 的時候,mysql 可以利用索引順序而直接取得已經排好序的資料。這種方式的 order by 基本上可以說是最優的排序方式了,因為 mysql 不需要進行實際的排序操作。需要注意的是使用索引排序也有很多限制。這個在後文中中解釋。

2 利用記憶體/磁碟檔案排序獲取結果

由於沒有可以利用的有序索引取得有序的資料,mysql需要通過相應的排序演算法,將取得的資料在sort_buffer_size系統變數所設定大小的排序區進行排序,這個排序區是每個thread 獨享的,所以說可能在同一時刻在 mysql 中可能存在多個 sort buffer 記憶體區域。

在mysql中filesort 的實現演算法有兩種:

1) 雙路排序:是首先根據相應的條件取出相應的排序欄位和可以直接定位行資料的行指標資訊,然後在sort buffer 中進行排序。

2) 單路排序:是一次性取出滿足條件行的所有字段,然後在sort buffer中進行排序。

在 mysql4.1 版本之前只有第一種排序演算法,第二種演算法是從mysql4.1開始的改進演算法,主要目的是為了減少第一次演算法中需要兩次訪問表資料的io操作,將兩次變成了一次,但相應也會耗用更多的 sort buffer 空間。典型的以空間換時間的優化方式。當然,mysql4.1開始的以後所有版本同時也支援第一種演算法,mysql主要通過比較系統引數 max_length_for_sort_data的大小和query語句所取出的字段型別大小總和來判定需要使用哪一種排序演算法。如果max_length_for_sort_data更大,則使用第二種優化後的演算法,反之使用第一種演算法。所以如果希望 order by 操作的效率盡可能的高,需要注意max_length_for_sort_data引數的設定。

二 優化order by

當無法避免排序操作時,又該如何來優化呢?很顯然,優先選擇第一種using index 的排序方式,在第一種方式無法滿足的情況下,盡可能讓 mysql 選擇使用第二種單路演算法來進行排序。這樣可以減少大量的隨機io操作,很大幅度地提高排序工作的效率。

1 加大 max_length_for_sort_data 引數的設定

在 mysql 中,決定使用老式排序演算法還是改進版排序演算法是通過引數 max_length_for_ sort_data 來決定的。當所有返回欄位的最大長度小於這個引數值時,mysql 就會選擇改進後的排序演算法,反之,則選擇老式的演算法。所以,如果有充足的記憶體讓mysql 存放須要返回的非排序字段,就可以加大這個引數的值來讓 mysql 選擇使用改進版的排序演算法。

2 去掉不必要的返回字段

當記憶體不是很充裕時,不能簡單地通過強行加大上面的引數來強迫 mysql 去使用改進版的排序演算法,否則可能會造成 mysql 不得不將資料分成很多段,然後進行排序,這樣可能會得不償失。此時就須要去掉不必要的返回字段,讓返回結果長度適應 max_length_for_sort_data 引數的限制。

3 增大 sort_buffer_size 引數設

置這個值如果過小的話,再加上你一次返回的條數過多,那麼很可能就會分很多次進行排序,然後最後將每次的排序結果再串聯起來,這樣就會更慢,增大 sort_buffer_size 並不是為了讓 mysql選擇改進版的排序演算法,而是為了讓mysql儘量減少在排序過程中對須要排序的資料進行分段,因為分段會造成 mysql 不得不使用臨時表來進行交換排序。

但是這個值不是越大越好:

1 sort_buffer_size 是乙個connection級引數,在每個connection第一次需要使用這個buffer的時候,一次性分配設定的記憶體。

2 sort_buffer_size 並不是越大越好,由於是connection級的引數,過大的設定+高併發可能會耗盡系統記憶體資源。

3 據說sort_buffer_size 超過2m的時候,就會使用mmap() 而不是 malloc() 來進行記憶體分配,導致效率降低。

三 參考資料

[1] mysql order by 的實現分析

[2] mysql order by實現原理分析和filesort優化

[3] mysql如何優化order by

Mysql之效能優化

mysql 資料庫效能優化之索引優化 大家都知道索引對於資料訪問的效能有非常關鍵的作用,都知道索引可以提高資料訪問效率。為什麼索引能提高資料訪問效能?他會不會有 是不是索引建立越多,效能就越好?到底該如何設計索引,才能最大限度的發揮其效能?這篇文章主要是帶著上面這幾個問題來做乙個簡要的分析,同時排除...

Mysql之效能優化

資料庫表的設計一般要遵循資料庫設計的三正規化,即第一正規化,第二正規化,第三正規化。第一正規化 1nf 資料庫表中的任一欄位都是單一的,不可再分的。換句話來說,就是資料庫表必須是一張二維表。第二正規化 2nf 資料庫表中的任一非關鍵字對任意候選關鍵字不存在部分函式依賴。部分函式依賴是指 候選關鍵字中...

效能優化之mysql索引優化

sql及索引優化 如何通過慢查詢日誌發現有問題的sql?查詢次數多且每次查詢占用時間長的sql 通常為pt query digest分析的前幾個查詢 io大的sql 注意pt query digest分析中的rows examine項 未命中索引的sql 注意pt query digest分析中ro...