![](/img/trans.png)
[英]Can MongoDB aggregation query other documents? In other words: recursive search in mongodb's side, not client's
[英]MongoDB - slow query on old documents (aggregation and sorting)
我有兩個用於測試的數據庫,每個數據庫包含數千/數十萬個文檔。 但具有相同的模式和 CRUD 操作。
我們稱之為 DB1 和 DB2。
我正在使用 Mongoose,DB1 在以下期間突然變得非常慢:
const eventQueryPipeline = [
{
$match: {
$and: [{ userId: req.body.userId }, { serverId: req.body.serverId }],
},
},
{
$sort: {
sort: -1,
},
},
];
const aggregation = db.collection
.aggregate(eventQueryPipeline)
.allowDiskUse(true);
aggregation.exect((err, result) => {
res.json(result);
});
在 DB2 中,相同的精確查詢以毫秒為單位運行,最長可達 10 秒
在 DB1 中,查詢永遠不會少於 40 秒。
我不懂為什么。 我會錯過什么? 我試圖面對文檔和索引,它們是相同的。 刪除集合並重新保存文檔,使速度恢復正常並且可以接受,但是為什么會發生這種情況? 有人有同樣的經歷嗎?
簡短的回答:
您應該創建以下索引:
{ "userId": 1, "serverId": 1, "sort": 1 }
更長的答案
根據您的代碼(我看到您有.allowDiskUse(true)
),看起來 mongo 正在嘗試對“大量”數據進行內存排序。 Mongo 默認對排序操作有 100MB 的系統內存限制,如果達到該限制,您可以允許它使用磁盤上的臨時文件來存儲數據。 您可以在此處閱讀更多相關信息:https: //www.mongodb.com/docs/manual/reference/method/cursor.allowDiskUse/
為了優化查詢的性能,您可以使用索引。 規划索引時應遵循的通用規則是 ESR(平等、排序、范圍)。 您可以在此處閱讀更多相關信息:https: //www.mongodb.com/docs/v4.2/tutorial/equality-sort-range-rule/
如果我們在創建復合索引時遵循該規則,我們將首先添加相等匹配,在您的情況下為"userId"和"serverId" 。 之后是排序字段,在您的情況下是"sort" 。
如果您需要根據某個范圍(例如大於 X 的某個值或大於 yday 的時間戳)額外過濾結果,您可以在“排序”之后添加它。
這意味着您的索引應如下所示:
schema.index({ userId: 1, serverId: 1, sort: 1 });
此外,您可能可以刪除allowDiskUse,並在aggregation.exec回調中處理錯誤(我假設aggregation.exect
是一個錯字)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.