錯誤訊息:
Out of sort memory, consider increasing server sort buffer size
Out of sort memory, consider increasing server sort buffer size
MySQL Out of sort memory(1038 error)代表排序過程中記憶體不足,常見於 ORDER BY、GROUP BY 或 JOIN 查詢。 大多數情況並不是單純記憶體不足,而是 SQL 設計或索引缺失造成。
一、發生原因
- ORDER BY 欄位沒有 Index
- 未使用 LIMIT 導致全表排序
- JOIN 產生大量中間資料
- GROUP BY 未優化
- sort_buffer_size 設定過小
👉 MySQL 排序流程:記憶體 → 不足 → 磁碟 → 最後錯誤
二、快速修復
💡 正式環境正在出狀況,需要馬上處理:如果網站正卡在排序查詢失敗的當下,優先用下面的
SET GLOBAL 立即解除,不需要重啟 MySQL,可以避免額外的服務中斷時間。方法一:立即生效,不需要重啟(建議優先使用)
mysql -u root -p SET GLOBAL sort_buffer_size = 4194304;
sort_buffer_size 是 MySQL 的動態變數,用 SET GLOBAL 指令修改會對之後新建立的連線立即生效,完全不需要重啟 MySQL。上面範例的 4194304 是位元組(bytes),等於 4MB。
⚠️ 注意:這樣修改只存在記憶體裡,MySQL 重啟後這個設定會消失,恢復成設定檔裡的原始值。如果要讓這個數值長期保留,請接著做下面的「永久保留設定」。
方法二:永久保留設定(MySQL 8.0 可一步到位)
如果你的 MySQL 是 8.0 以上版本,可以用 SET PERSIST 指令,一次同時做到「立即生效」與「寫入永久設定、未來重啟也不會跑掉」,不需要額外編輯設定檔或重啟:
SET PERSIST sort_buffer_size = 4194304;
如果是 MySQL 8.0 以前的版本沒有 SET PERSIST,則需要手動把設定寫進設定檔,讓它在未來重啟後依然保留:
/etc/my.cnf.d/server.cnf
[mysqld] sort_buffer_size = 4M
這種情況下,設定檔的變更要等到下一次系統重啟才會被讀取套用;但前面方法一的 SET GLOBAL 已經讓目前執行中的 MySQL 立即生效了,不需要為了讓設定檔生效而現在去重啟服務。
🔍 確認設定是否生效
mysql -u root -p SHOW VARIABLES LIKE 'sort_buffer_size';
✔ 若數值未改變,代表指令尚未成功執行,或是你檢查的是新開的連線以外的 session 值
三、根本解法(SQL 優化)
ALTER TABLE orders ADD INDEX idx_created_at (created_at);
SELECT id, created_at FROM orders ORDER BY created_at DESC LIMIT 50;
SELECT id, name FROM users;
EXPLAIN SELECT * FROM orders ORDER BY created_at;
👉 type = ALL / key = NULL = 沒有索引
延伸閱讀(MySQL 錯誤排除系列・2026)
FAQ 常見問題
MySQL Out of sort memory 是什麼錯誤?
代表 MySQL 在排序(ORDER BY 或 GROUP BY)時記憶體不足,通常因 SQL 沒有索引或 sort_buffer_size 不足造成。
只調 sort_buffer_size 能解決嗎?
不能完全解決,只能暫時改善,真正原因多半是 SQL 設計或索引問題。
為什麼 ORDER BY 會爆記憶體?
因為沒有索引時 MySQL 需要全表排序,導致 sort buffer 使用過高而爆掉。
sort_buffer_size 建議多少?
建議 2M~4M,中大型系統最多 8M,過大會影響整體 RAM 使用。
如何判斷 SQL 有問題?
使用 EXPLAIN,如果 type=ALL 或 key=NULL 表示沒有使用索引。
Index 一定能解決嗎?
大多數情況可以大幅改善排序效能,避免全表掃描。
CodeIgniter 會影響嗎?
不會,問題本質是 MySQL SQL 查詢設計。
會影響網站嗎?
會,查詢失敗會導致頁面錯誤或 API 無法回應。
修改 sort_buffer_size 一定要重啟 MySQL 嗎?
不一定。sort_buffer_size 是動態變數,用 SET GLOBAL 指令修改會立即生效、不需要重啟,只對之後新建立的連線有效;MySQL 8.0 可用 SET PERSIST 一個指令同時做到立即生效與永久保留,不需要額外重啟。
這是 MySQL 錯誤排除系列文章之一,包含記憶體、連線、鎖定三大類問題。
