我正试图从MongoDb中检索100000个文档,如下所示,返回集合需要很长时间。
var query = Query.EQ("Status", "E");
var items = collection.Find(query).SetLimit(100000).ToList();
或
var query = Query.GT("_id", idValue);
var items = collection.Find(query).SetLimit(100000).ToList();
解释:
{
"cursor" : "BtreeCursor _id_",
"nscanned" : 1,
"nscannedObjects" :1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" :
{
"_id" :[[ObjectId("4f79a64eca98b5fc0e5ae35a"),
ObjectId("4f79a64eca98b5fc0e5ae35a")]]
}
}
任何提高查询性能的建议。我的桌子上有200万份文件。
-Venkat
这个问题也在谷歌群组上被问到:
https://groups.google.com/forum/?fromgroups#!主题earchin/mongodb用户/10000/mongodb用户/a6FHFp5aOnA
当我回答谷歌群组的问题时,我试图重现这一点,但无法观察到任何缓慢。我能够在2-3秒内阅读100000个文档,这取决于文档是接近集合的开头还是末尾(因为我没有创建索引)。
我对谷歌小组问题的回答有更多的细节,还有一个我用来尝试复制的测试程序的链接。
如果不为集合创建索引,MongoDB将进行全表扫描-这是最慢的方法。
您可以为查询运行explain()。Explain将告诉您查询使用了哪些索引(如果有的话)、扫描文档的数量和总查询持续时间。
如果您的查询命中了所有索引,并且执行速度仍然很慢,那么您可能会遇到集合/RAM大小的问题。
当收集数据+索引适合内存时,MongoDB是最快的。如果您的集合大小大于可用RAM,则性能下降幅度非常大。
您可以使用totalSize()
、totalIndexSize()
或validate()
(这些是shell命令)检查集合的大小。
根据您提供的信息,我的最佳猜测是您的文档大小太大,延迟不一定在mongo服务器上,而是在将结果集传输回您的应用程序机器上。看看你在集合中的平均文档大小,例如,你有大型嵌入式数组吗?
比较使用.SetFields方法只选择一个字段时的响应时间(请参阅此处的示例如何使用C#MongoDB驱动程序检索字段的子集?)。如果响应时间明显加快,那么您就知道这就是问题所在。
您定义了索引吗?
http://www.mongodb.org/display/DOCS/Indexes
有几件事需要检查:
- 您的查询索引是否正确
- 如果您的查询是索引的,那么数据本身在内存中的几率是多少?如果你有20GB的数据和4GB的RAM,那么你的大部分数据都而不是在内存中,这意味着你的磁盘要做很多工作
- 10万个文档代表了多少数据?如果你的文档真的很大,它们可能会占用所有可用的磁盘IO,或者可能占用网络?您是否有足够的空间将其存储在客户端的RAM中
您可以使用iostat
(一个常见的linux工具)或perfmon
(在Windows下)检查磁盘使用情况。如果您在运行查询时运行这些,您应该了解磁盘的情况。
否则,您将不得不对有多少数据在这里移动进行一些推理。一般来说,返回10万个对象的查询并不是很快(在MongoDB或SQL中不是这样)。这比人类通常在一个屏幕上消耗的数据还要多,所以你可能想制作更小的批次,读取10次10k个对象,而不是一次100k个对象。