如何在没有缓存的情况下检查 mongodb 查询性能
我有一个查询需要很长时间才能完成。 我喜欢做一些性能测试,但在检查一次(当前需要约 30 秒)后,查询开始运行得更快(< 1 秒)。 我认为它必须与 mongodb 缓存一起使用。 有没有办法禁用 mongodb 缓存或其他方法来检查性能?
我正在使用 mongohq 托管的 mongodb。使用 Ruby on Rails 3 进行编程。 以下是解释:
{"cursor"=>"BtreeCursor start_-1", "nscanned"=>5276, "nscannedObjects"=>5276, "n"=>25, "millis"=>3264, "nYields"=>0, "nChunkSkips"=>0, "isMultiKey"=>false, "indexOnly"=>false, "indexBounds"=>{"start"=>[[{"$maxElement"=>1}, {"$minElement"=>1}]]}, "allPlans"=>[{"cursor"=>"BtreeCursor attendees_count_-1", "indexBounds"=>{"attendees_count"=>[[1.7976931348623157e+308, 1]]}}, {"cursor"=>"BtreeCursor images_count_-1", "indexBounds"=>{"images_count"=>[[1.7976931348623157e+308, 2]]}}, {"cursor"=>"BtreeCursor start_-1", "indexBounds"=>{"start"=>[[{"$maxElement"=>1}, {"$minElement"=>1}]]}}, {"cursor"=>"BtreeCursor start_-1_end_-1", "indexBounds"=>{"start"=>[[{"$maxElement"=>1}, {"$minElement"=>1}]], "end"=>[[{"$maxElement"=>1}, {"$minElement"=>1}]]}}, {"cursor"=>"BtreeCursor attendees._id_1 multi", "indexBounds"=>{"attendees._id"=>[[BSON::ObjectId('4f0b621e94bb688563000007'),BSON::ObjectId('4f0b621e94bb688563000007')], [BSON::ObjectId('4f0b647d5a8c00acde05236f'), BSON::ObjectId('4f0b647d5a8c00acde05236f')], [BSON::ObjectId('4f0b647d5a8c00acde052370'), BSON::ObjectId('4f0b647d5a8c00acde052370')], [BSON::ObjectId('4f0b647d5a8c00acde052371'), BSON::ObjectId('4f0b647d5a8c00acde052371')], [BSON::ObjectId('4f0b647d5a8c00acde052372'), BSON::ObjectId('4f0b647d5a8c00acde052372')], [BSON::ObjectId('4f0b647d5a8c00acde052373') ... (lots of Object IDs)]]}}}
请注意,我不得不截断一些解释,因为它太长了。 哪里有“很多对象 ID”,哪里就有很多对象 ID(~400)。
谢谢大家
I have a query that takes too long to finish.
I like to do some performance tests but after I check for one time (that takes currently ~30 seconds) the query start to run a lot faster (< 1 second).
I assume it has to be with the mongodb caching.
Is there a way to disable caching for mongodb or another way I can check the performance?
I'm using mongodb hosted in mongohq. Program with Ruby on Rails 3.
Here is the explain:
{"cursor"=>"BtreeCursor start_-1", "nscanned"=>5276, "nscannedObjects"=>5276, "n"=>25, "millis"=>3264, "nYields"=>0, "nChunkSkips"=>0, "isMultiKey"=>false, "indexOnly"=>false, "indexBounds"=>{"start"=>[[{"$maxElement"=>1}, {"$minElement"=>1}]]}, "allPlans"=>[{"cursor"=>"BtreeCursor attendees_count_-1", "indexBounds"=>{"attendees_count"=>[[1.7976931348623157e+308, 1]]}}, {"cursor"=>"BtreeCursor images_count_-1", "indexBounds"=>{"images_count"=>[[1.7976931348623157e+308, 2]]}}, {"cursor"=>"BtreeCursor start_-1", "indexBounds"=>{"start"=>[[{"$maxElement"=>1}, {"$minElement"=>1}]]}}, {"cursor"=>"BtreeCursor start_-1_end_-1", "indexBounds"=>{"start"=>[[{"$maxElement"=>1}, {"$minElement"=>1}]], "end"=>[[{"$maxElement"=>1}, {"$minElement"=>1}]]}}, {"cursor"=>"BtreeCursor attendees._id_1 multi", "indexBounds"=>{"attendees._id"=>[[BSON::ObjectId('4f0b621e94bb688563000007'),BSON::ObjectId('4f0b621e94bb688563000007')], [BSON::ObjectId('4f0b647d5a8c00acde05236f'), BSON::ObjectId('4f0b647d5a8c00acde05236f')], [BSON::ObjectId('4f0b647d5a8c00acde052370'), BSON::ObjectId('4f0b647d5a8c00acde052370')], [BSON::ObjectId('4f0b647d5a8c00acde052371'), BSON::ObjectId('4f0b647d5a8c00acde052371')], [BSON::ObjectId('4f0b647d5a8c00acde052372'), BSON::ObjectId('4f0b647d5a8c00acde052372')], [BSON::ObjectId('4f0b647d5a8c00acde052373') ... (lots of Object IDs)]]}}}
Notice that I had to truncate some of the explain because it was too long.
Where there is "lots of Object IDs" there were lots of Object IDs (~400).
Thanks all
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想你无法阻止 Mongo 准备查询计划(这就是 mongo 的工作原理)。
所以,在查询统计数据之前..
来清除所有集合的计划缓存
I guess you can not stop Mongo from preparing the query plan (that's how mongo works).
So, Before query stats..
1. Clear the plan cache of all collections by
当您第一次运行查询时,数据集是内存映射的,但尚未分页到实际内存中,请参阅
因为您从磁盘(慢)分页到 RAM(快),所以初始运行速度很慢,然后,除非您有内存压力,否则该数据将保留在 RAM 中,并且对该数据集的所有后续查询都将很快。
这就是 MongoDB 的设计原理,将数据集加载到内存中的过程通常称为“预热”数据库,只有在预热之后(在您的情况下是第一个查询),您才能获得真正的性能。
值得注意的是,您的初始查询似乎仍然需要很长时间才能返回。您应该确保它有效地使用索引。调查的最佳起点是 explain() 页面。
When you are first running the query, the data set is memory mapped, but has not been paged into actual memory, see Caching on the MongoDB site. So, the OS has to page that data set into memory and then you get your query run and result.
Because you are paging in from the disk (slow) into RAM (fast) the initial run is slow, and then, unless you have memory pressure, that data will stay in RAM and all of your subsequent queries on that data set will be fast.
This is how MongoDB is designed to function, the process of loading your data set into memory is often called "warming up" the database and it is only after that warming up (in your case the first query) that you get the true performance.
It is worth noting that your initial query still seems to take a very long time to return. You should make sure it is using indexes effectively. The best place to start in that investigation is the explain() page.
您可以使用 db.collection.getPlanCache().clear() 删除集合的所有缓存查询计划。
https://docs.mongodb.com/v3.2/reference /方法/PlanCache.clear/
You can use
db.collection.getPlanCache().clear()
to remove all cached query plans for a collection.https://docs.mongodb.com/v3.2/reference/method/PlanCache.clear/