MySQL 優化器在處理 ORDER BY 時,會嘗試利用索引避免額外排序或直接消除排序操作。理解其決策邏輯對查詢調優至關重要。以下基於官方文檔與源碼邏輯 (sql/sql_select.cc) 總結關鍵場景。
SELECT column1 FROM Table1 ORDER BY 'x';
優化器識別常量排序無意義,直接拋棄 ORDER BY 子句 (Dead Code Elimination)。
SELECT column1 FROM Table1 ORDER BY column1;
若 column1 有索引,優化器直接按索引順序掃描,**無需額外排序**,返回有序結果。
SELECT column1 FROM Table1 ORDER BY column1 + 1;
雖可利用索引快速讀取數值 (索引掃描比全表掃描快),但**結果集仍需完整排序**,因表達式破壞了索引原有順序。
SELECT * FROM Table1 WHERE column1 > 'x' AND column2 > 'x' ORDER BY column2;
即使 column1、column2 均有索引,優化器選擇 column1 索引驅動訪問 (因 WHERE 條件),ORDER BY column2 **不影響驅動表選擇**,仍需對結果集排序。相關源碼:test_if_order_by_key()、test_if_skip_sort_order()。
當無法利用索引順序時,MySQL 使用內部快速排序,涉及 sort_buffer_size、max_length_for_sort_data 等參數控制內存排序 vs 磁盤臨時文件排序。詳見官方文檔 ORDER BY Optimization 及源碼 create_sort_index()。
ORDER BY 列與索引順序一致 (含方向 ASC/DESC)。ORDER BY col1, col2 混合方向或包含表達式。sort_buffer_size 減少磁盤排序。EXPLAIN 中 Using filesort 表示觸發額外排序,需優化。