簡體   English   中英

MongoDB - 對舊文檔的慢查詢(聚合和排序)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM