Node.js Mongo查找查询需要2分钟

Node.js Mongo查找查询需要2分钟,node.js,mongodb,mongodb-query,node-mongodb-native,Node.js,Mongodb,Mongodb Query,Node Mongodb Native,我收集了大约75000份文件 数据库的总大小约为45GB。 在75k个文档中,约45k个文档的大小为900KB(约42GB),其余文档的大小约为120KB 每个文档都映射到另一个集合中的custIdObjectId,并具有时间戳,两者都已索引 现在我需要获取上个月某个特定的custId的文档。 总数约为5500份文件。此custId包含大小约为120 KB的小文档 以下是我的疑问: db.mycollection.find( { custId:ObjectId("CUST_OBJECT_

我收集了大约75000份文件

数据库的总大小约为45GB。
在75k个文档中,约45k个文档的大小为900KB(约42GB),其余文档的大小约为120KB

每个文档都映射到另一个集合中的
custId
ObjectId,并具有
时间戳
,两者都已索引

现在我需要获取上个月某个特定的
custId
的文档。 总数约为5500份文件。此
custId
包含大小约为120 KB的小文档

以下是我的疑问:

db.mycollection.find(
{
    custId:ObjectId("CUST_OBJECT_ID_HERE"),
    timestamp:{$gte:one_month_ago_date, $lt:current_date}
}).sort({timestamp:-1})
不过,查询需要2分钟才能获取所有记录。这是因为文件的数量还是较大文件的大小?有没有办法解决这个问题

注意: 从nodejs启动查询需要2分钟。如果我在MongoShell上启动它,它会很快返回,但可能是因为它只获取了前50条记录。当我将
.count()
附加到mongo shell上的查询时,花了2分钟时间返回计数

更新:
索引详细信息:

"wiredTiger" : {
    "nindexes" : 3,
    "totalIndexSize" : 2396160,
    "indexSizes" : {
        "_id_" : 1138688,
        "custId_1" : 598016,
        "timestamp_1" : 659456
    }
}
解释输出:(带排序)


这就是索引的作用

为timestamp和custId创建索引(使用两者的复合索引将是最有效的),这样就可以了。由于按时间戳排序,在复合索引中,使时间戳成为第一个(顺序很重要)


这是在mongo中创建复合索引的代码:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    //...
});

userSchema.index({timestamp: 1, custId: 1});

mongoose.model('User', userSchema);
module.exports = userSchema;

这就是索引的作用

为timestamp和custId创建索引(使用两者的复合索引将是最有效的),这样就可以了。由于按时间戳排序,在复合索引中,使时间戳成为第一个(顺序很重要)


这是在mongo中创建复合索引的代码:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    //...
});

userSchema.index({timestamp: 1, custId: 1});

mongoose.model('User', userSchema);
module.exports = userSchema;
请尝试以下索引:

db.mycollection.createIndex({custId:1,timestamp:1}, {background:true})
请尝试以下索引:

db.mycollection.createIndex({custId:1,timestamp:1}, {background:true})

以上答案都是完全正确的。我只想把我的2美分放进去。这个答案在很大程度上取决于您可用的内存,以及您需要返回的信息是“实时”的还是可以以某种方式缓存的

Mongodb因内存使用而臭名昭著。(我喜欢mongodb,但记忆是致命弱点)。第二,如上所述,在进行查询之前,您可以改进查询结果,这在时间、读取和核心使用方面都是一个很大的优势。当涉及到文档存储时,您可能(或将)找到一个正确设置的Redis缓存,这也将极大地帮助您降低响应时间

显然,这需要内存,在您的情况下需要平衡(包括负载平衡)。它是内存、速度和磁盘使用率的适当组合(即使是SSD),这将帮助您根据系统要求平衡这些查询请求


希望这有点帮助

以上答案都是完全正确的。我只想把我的2美分放进去。这个答案在很大程度上取决于您可用的内存,以及您需要返回的信息是“实时”的还是可以以某种方式缓存的

Mongodb因内存使用而臭名昭著。(我喜欢mongodb,但记忆是致命弱点)。第二,如上所述,在进行查询之前,您可以改进查询结果,这在时间、读取和核心使用方面都是一个很大的优势。当涉及到文档存储时,您可能(或将)找到一个正确设置的Redis缓存,这也将极大地帮助您降低响应时间

显然,这需要内存,在您的情况下需要平衡(包括负载平衡)。它是内存、速度和磁盘使用率的适当组合(即使是SSD),这将帮助您根据系统要求平衡这些查询请求


希望这有点帮助

这是因为它的种类。它必须将整个东西加载到内存或硬盘中。由于数据库的大小,它可能正在加载到硬盘上,速度很慢。您可以尝试只指定需要检索的属性,这些属性将使它更轻,并且可能使它适合内存。我认为在使用排序时,它也只会使用1个索引,它会选择时间戳索引而忽略custId索引。您可以尝试为custId和timestamp添加一个复合索引。如果您不需要一个all docs at ONE,也可以使用分页。此集合上有哪些索引?你试过mongodb解释吗?没有mongo shell内部的排序,这个查询是如何执行的?@Astro,如前所述,
custId
timestamp
被索引。不排序需要2分钟。排序增加了29秒。@Love Kesh,不,我需要一个一个的所有文档。这是因为排序。它必须将整个东西加载到内存或硬盘中。由于数据库的大小,它可能正在加载到硬盘上,速度很慢。您可以尝试只指定需要检索的属性,这些属性将使它更轻,并且可能使它适合内存。我认为在使用排序时,它也只会使用1个索引,它会选择时间戳索引而忽略custId索引。您可以尝试为custId和timestamp添加一个复合索引。如果您不需要一个all docs at ONE,也可以使用分页。此集合上有哪些索引?你试过mongodb解释吗?没有mongo shell内部的排序,这个查询是如何执行的?@Astro,如前所述,
custId
timestamp
被索引。不排序需要2分钟。使用排序,它会增加29秒。@Love Kesh,不,我需要一个一个的所有文档。你能详细说明复合索引吗?如前所述,我已经索引了
custId
timestamp
,但不是复合索引。如果你能提到如何使用猫鼬,那就更好了。@DushyantBangal请参考@Astro answear以创建复合(多键组合)索引。请查看复合索引的Mongoose文档:
https://docs.mongodb.com/manual/indexes/#Indexes-康普