| 算法 | 版本 | 流程 | 特點 |
| 雙路排序 | ≤4.0 | 1. 讀取排序鍵+行指針 2. Sort Buffer 排序 3. 再按指針回表讀取其餘欄位 | 兩次訪問表,IO 多,佔用 Sort Buffer 少 |
| 單路排序 | ≥4.1 | 1. 一次性讀取所有需返回欄位 2. Sort Buffer 排序 3. 直接輸出 | 一次訪問表,IO 少,佔用 Sort Buffer 大 |
關鍵決策參數:max_length_for_sort_data
MySQL 通過比較 所有返回欄位總長度 與 max_length_for_sort_data 決定用哪種算法:
- 總長度 < 參數值 → 單路排序
- 總長度 ≥ 參數值 → 雙路排序
三大優化手段
1. 加大 max_length_for_sort_data 強制單路排序
SET GLOBAL max_length_for_sort_data = 8192; -- 默認 1024,視記憶體調大
前提:記憶體充足,且返回欄位總長度可控。
2. 精簡 SELECT 列表,縮小排序行寬度
- 嚴禁
SELECT * 帶 ORDER BY
- 僅選取業務必要欄位,讓行長度自然落入參數閾值內
- 若有大字段(TEXT/BLOB/VARCHAR長文),務必排除
3. 調大 sort_buffer_size 減少分段排序
SET GLOBAL sort_buffer_size = 4M; -- 默認 256K,連接級參數
關鍵權衡:
- 過小 → 排序數據分段 → 臨時表交換 → 極慢
- 過大 → 連接數 × 參數值 = 總記憶體壓力 → OOM 風險
- 傳聞:>2M 可能觸發
mmap() 而非 malloc(),效率反降(需實測驗證)
實戰檢查清單
EXPLAIN 確認是否 Using filesort
- 若是,檢查
SELECT 列表是否包含大字段/非必要字段
- 評估記憶體,適度調大上述兩參數
- 嘗試建立覆蓋索引消除 Filesort(最徹底方案)
順序:索引優化 > 算法優化 > 參數調優。能上索引絕不調參數,能精簡欄位絕不加 Buffer。
- 上一篇文章: MySQL slave_net_timeout 參數調優:解決 5.6 升級後頻繁重連 Warning 案例
- 下一篇文章: MySQL 5.6 ICP 特性深度解析:Index Condition Pushdown 如何減少回表 IO
Copyright ©
程式碼之家 All Rights Reserved