MongoDB 無法排序:Sort operation used more than the maximum 33554

2023/02/05閱讀時間約 3 分鐘
當使用以下語法對 Log 這個 Collection 依照 CreateTime 做倒序查詢
db.Log.find().sort({CreateTime: -1})
MongoDB 回傳了以下 Error Msg
Error: error: {
"ok" : 0,
"errmsg" : "Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.",
"code" : 96,
"codeName" : "OperationFailed"
}

發生原因

MongoDB 在排序時會將資料全部載入記憶體,之後在記憶體中進行排序,而預設開放給排序的記憶體只有 32 MB,因此在大量資料排序時就會引發該錯誤。

解決方案

建立索引

此範例為對 Log 這個 Collection 的 CreateTime 建立降冪排序的 Index
db.Log.createIndex({"CreateTime":-1})
可以用以下指令來查詢此 Collection 上有多少組 Index
db.Log.getIndexes()
增加索引會導致寫入資料速度變慢,且由於需要額外儲存 Index 資訊,會增加儲存資料所佔的空間,但對排序與搜尋有著正向的效能提升,若該欄位時常使用 where 與 sort 則建議可加上索引提高效能。

增加排序可用的記憶體空間

此範例為增加至 320 MB
db.adminCommand({setParameter:1,internalQueryExecMaxBlockingSortBytes:335544320})
若在不增加索引的狀況下修改預設記憶體大小,會導致排序時佔用更多記憶體空間進而影響到資料庫效能,不是一個治標的做法,建議僅在能確保使用量與不適合加入索引時謹慎使用此方案。

結論

在此案例裡,我採取的解決方案是雙管齊下,目的是確保指令可以正確執行,而增加記憶體上限是評估 MongoDB 主機記憶體總大小尚可負擔,可依照需求彈性決定是否對 Collection 上 Index 而同時確保可正常排序查詢

參考資料

分享網站開發的前端、後端、資料庫與部屬維運技術,並記錄在工作上的心得
留言0
查看全部
發表第一個留言支持創作者!
從 Google News 追蹤更多 vocus 的最新精選內容