MySQL 的查詢優化器相較於 Oracle、PostgreSQL 等商用資料庫,演算法選擇較為單一。本文深入剖析 MySQL 唯一的 Join 演算法——Nested Loop Join,以及兩種排序演算法的運作機制與調優關鍵參數 max_length_for_sort_data。
MySQL 不支援 Hash Join、Sort Merge Join,所有多表連接均採用 Nested Loop Join(巢狀迴圈連接)。
優化關鍵:
EXPLAIN 檢查 type 是否為 ref 或 eq_refSort Buffer 中排序特點:兩次 I/O,排序緩衝區較小,適用於需回傳欄位較大的場景。
Sort Buffer 排序「排序欄位 + 行指標」特點:單次 I/O,但佔用更多 Sort Buffer,適用於需回傳欄位總長度較小的場景。
max_length_for_sort_dataMySQL 依據「所有回傳欄位最大長度」是否小於此參數,決定採用哪種演算法:
SET GLOBAL max_length_for_sort_data = 4096; -- 預設 1024,視記憶體調大
若系統記憶體充足,調大此值可強制使用單路排序,顯著提升 ORDER BY、GROUP BY、DISTINCT 等排序操作效能。
EXPLAIN SELECT * FROM orders WHERE user_id=100 ORDER BY created_at DESC LIMIT 20;
觀察 Extra 欄位:
Using filesort:觸發排序optimizer_trace 可見具體演算法選擇| 維度 | Nested Loop Join | 單路排序 | 雙路排序 |
|---|---|---|---|
| 適用場景 | 所有 Join | 回傳欄位總長度小 | 回傳欄位總長度大 |
| I/O 次數 | 視索引而定 | 1 次 | 2 次 |
| 記憶體壓力 | 低 | 高 | 低 |
| 調優手段 | 加索引、小表驅動大表 | 調大 max_length_for_sort_data | 無法避免,縮減 SELECT * |
理解核心演算法,才能對症下藥,寫出高效 SQL。