MongoDB查询在mongo-shell上执行的时间为1ms,但在NodeJS上的执行时间为400ms以上

我有一个大的MongoDB集合,包含超过2GB的原始数据,我使用一个非常简单的查询来从集合中获取特定的文档。 文档大小的范围从10KB到4MB,Id字段被定义为索引。

这是我正在使用的查询(与mongojs模块):

 db.collection('categories').find({ id: category_id }, function(err, docs) { callback(err, docs.length ? docs[0] : false); }).limit(1); 

当我使用MongoDB shell或Robomongo等GUI来执行这个查询时,无论物理大小如何,大约需要1ms的时间,但是当我在NodeJS上执行完全相同的查询时,响应时间从2ms到2s以上取决于数据量。 我只测量接收响应所需的时间,即使在.explain()等待超过500毫秒的情况下,MongoDB分析器( .explain() )显示仅执行一个毫秒即可执行查询。

现在,我可能做错了什么,但我不知道它是什么。 我对NodeJS比较陌生,但过去我曾经使用过MongoDB和PHP,而且从来没有遇到这样的性能问题,所以我倾向于认为我可能以某种方式滥用NodeJS。

我也试过在WebStorm上使用SpyJS进行分析,我看到有很多bson.deserialize调用快速地汇总成一个大堆栈,但是我无法进一步调查,因为SpyJS总是在这个时候崩溃。 可能有关,但我仍然不知道如何处理它。

请指教,任何线索将不胜感激。

编辑:这是db.categories.getIndexes()的结果:

 [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "my_db.categories" }, { "v" : 1, "key" : { "id" : 1 }, "name" : "id_1", "ns" : "my_db.categories" } ] 

我也尝试使用findOne没有任何区别:

 db.collection('categories').findOne({ id: category_id }, function(err, doc) { callback(err, doc || false); }); 

我的猜测是.limit(1)被忽略,因为callback是提前提供的。 一旦find一个callback将执行查询,并且只有在查询发送到mongo后, .limit修饰符才会尝试调整查询,但是太迟了。 重新编码,看看是否解决了这个问题:

 db.collection('categories').find({ id: category_id }).limit(1).exec( function(err, docs) { callback(err, docs.length ? docs[0] : false); }); 

很可能你需要在你的对象中有规范化和非规范化数据的组合。 一次发送4MB的数据似乎相当繁重,而且可能会导致任何浏览器出现问题,这些浏览器将会分析数据。

最有可能的是,您应该存储前100个产品,产品的第一页,或者一些较小的子集,这对您的应用程序来说是合理的。 这可能是按字母顺序排列的最热门的,最stream行的,最新的或您确定的某个其他特定于应用程序的指标。

在编辑类别时,您将使用$ push / $ slice方法来确保避免无限制的数组增长。

然后,当您实际浏览结果时,您将按类别对单个产品表单独进行查询。 (索引那个)

我已经写在这之前: https : //stackoverflow.com/a/27286612/68567