admin管理员组文章数量:1391955
In MongoDB, does .find({...}).limit(#)
really limit the number of queries?
I mean, when you do db.collection.find(condition)
, doesn't it already waste putational power to query all the results that match the given condition? If so, then does adding .limit()
after it just strip off the unneeded elements from the query results?
Thanks a lot for clarifying this up!
In MongoDB, does .find({...}).limit(#)
really limit the number of queries?
I mean, when you do db.collection.find(condition)
, doesn't it already waste putational power to query all the results that match the given condition? If so, then does adding .limit()
after it just strip off the unneeded elements from the query results?
Thanks a lot for clarifying this up!
Share Improve this question edited Sep 22, 2017 at 17:57 CommunityBot 11 silver badge asked Jul 25, 2014 at 6:34 MariaMaria 3,5357 gold badges35 silver badges49 bronze badges3 Answers
Reset to default 5db.collection.find
returns a cursor
, not an array of results or similar. From the documentation:
When the
find()
method “returns documents,” the method is actually returning acursor
to the documents.
The documents are actually located when you iterate the cursor. So calling .limit
tells the cursor when to say it's done iterating.
More about cursors here: http://docs.mongodb/manual/core/cursors/#read-operations-cursors
limit() is not used for post filtering of data. You can figure out this using explain(). For example, I have fired 2 queries 1)db.album.find().explain() 2) db.album.find().limit(5).explain(); here is resultant:
> db.album.find().explain()
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 1000,
"nscannedObjects" : 1000,
"nscanned" : 1000,
"nscannedObjectsAllPlans" : 1000,
"nscannedAllPlans" : 1000,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 54,
"nChunkSkips" : 0,
"millis" : 12,
"server" : "delbsinha25125:27017",
"filterSet" : false
}
> db.album.find().limit(5).explain()
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 5,
"nscannedObjects" : 5,
"nscanned" : 5,
"nscannedObjectsAllPlans" : 5,
"nscannedAllPlans" : 5,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"server" : "delbsinha25125:27017",
"filterSet" : false
}
As you can see from the above execution plan, the one with limit has scanned only 5 objects.
>
So I tried to answer this question about 5 days ago but then found some interesting things that I had to actually investigate.
Limit is applied after sort and find, however, not before iteration of those results within the mongod
(MongoDB) server itself, as such this means that if done right you can save a lot of putational power using limit. @Bipul's answer is a perfect eample of this but it doesn't go as far as to show the true limitations of what MongoDB can achieve here.
It should be noted that if you are using the latest version of MongoDB there is actually a bug with limit which causes etra entries to be scanned: https://jira.mongodb/browse/SERVER-14712 which was one of the things I actually found while attempting to answer this question.
It should be noted that the bug mentioned above only effects inde usage with limit.
Now considering @Bipuls answer without inde usage there is actually two sides to this story, one being what he has shown but the other also being if you add a sort:
> db.rooms.find().sort({d:1}).limit(2).explain()
{
"clauses" : [
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 2,
"nscannedObjects" : 5,
"nscanned" : 5,
"scanAndOrder" : true,
"indexOnly" : false,
"nChunkSkips" : 0
},
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"scanAndOrder" : true,
"indexOnly" : false,
"nChunkSkips" : 0
}
],
"cursor" : "QueryOptimizerCursor",
"n" : 2,
"nscannedObjects" : 5,
"nscanned" : 5,
"nscannedObjectsAllPlans" : 5,
"nscannedAllPlans" : 5,
"scanAndOrder" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"server" : "ubuntu:27017",
"filterSet" : false
}
The size of the collection being 5, you can see the limit has been applied after sort as such it shows that the collection had to be fully scanned and since this query has no inde it would have been a full inde scan and your putational saving will be nothing more than "by the looks of it".
Now if you add an inde this is different, it can actually use the order of the inde to stop a full scan and load only as far as your limit goes, however, due to the bug above it will always scan one more than needed, but that is an inde scan, not an actual document being loaded (depending on whether your queries find() is covered or not).
So to sum up, limit, when used correctly, can stop MongoDB from having to load ecessive documents, not only saving your working set but also your IO bandwidth. If you can use limit correctly with the inde etc then I would definitely remend it.
本文标签: javascriptMongoDB truth behind find()limit()Stack Overflow
版权声明:本文标题:javascript - MongoDB: truth behind find({...}).limit(#) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744714076a2621296.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论