mysql 排序長度限制之max_length_for_sort_data以及mysql兩種排序算法


SET max_length_for_sort_data = 1024

SHOW VARIABLES LIKE '%max_length_for_sort_data%';

查詢:SELECT * FROM CS_COLUMNS ORDER BY table_name,column_name LIMIT 0,100

錯誤代碼: 1815
Internal error: IDB-2015: Sorting length exceeded. Session variable max_length_for_sort_data needs to be set higher.

執行耗時 : 7.171 sec

mysql有兩種文件排序算法(雙路排序和單路排序),如果需要排序的列的總大小加上order by列的大小超過了 max_length_for_sort_data定義的字節,mysql就會使用雙路排序,當任何需要的列甚至不是用order by的列(text.blob的時候),也會使用雙路排序,(可以使用substtring() 把這些列轉化為可以單路排序的列)。

可以通過改變 max_length_for_sort_data變量的值來影響mysql選擇的算法。因為單路排序為將要排序的每一行創建了固定的緩沖區,varchar列的最大長度是 max_length_for_sort_data規定的值,而不是排序數據的實際大小。

當mysql不得不對text。blob列進行排序時,它只會使用前綴並忽略剩余的值,這是因為不得不分配固定大小的結構來容納數據並且從外部存儲中將前綴拷貝回結構中,可以使用max_sort_length定義前綴應該是多大。

mysql並不會真正的顯示使用的是哪種算法,如果增大了max_length_for_sort_data的值,並且磁盤使用率上升,cpu使用率下降,sort_merge_passes的值比以前增加的更快,也許該強制排序使用單路排序算法。


雙路排序:
讀取行指針和order by列,對他們進行排序,然后掃描已經排序好的列表,按照列表中的值重新從列表中讀取對應的數據輸出。
雙路排序的開銷可能會非常巨大,因為他會讀取表兩次,第二次讀取會引發大量的隨機IO,對於myisam淶說,這個代價尤其昂貴,myisam表利用系統調用去提取每行的數據。

單路排序:
讀取查詢需要的所有列,按照order by 列對他們進行排序,然后掃描排序后的列表進行輸出,它的效率更快一些,避免了第二次讀取數據。並且把隨機IO變成了順序IO,但是它會使用更多的空間,因為它把每一行都保存在內存中了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM