15

我有一个查询需要很长时间才能完成。我喜欢做一些性能测试,但是在我检查一次(目前需要大约 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)。

谢谢大家

4

3 回答 3

7

我想你不能阻止 Mongo 准备查询计划(这就是 mongo 的工作方式)。所以,在查询统计之前.. 1.清除所有集合的计划缓存

>db.colllction_name.getPlanCache().clear()
  1. 使用Profiler记录慢查询(参见 mongo 文档),
  2. 处理查询以优化它,
  3. 再次清除缓存,再次检查查询性能。
于 2018-08-28T09:07:34.060 回答
5

首次运行查询时,数据集是内存映射的,但尚未分页到实际内存中,请参阅MongoDB 站点上的缓存。因此,操作系统必须将该数据集分页到内存中,然后您才能运行查询并获得结果。

因为您正在从磁盘(慢)分页到 RAM(快),所以初始运行很慢,然后,除非您有内存压力,否则该数据将保留在 RAM 中,并且您对该数据集的所有后续查询都会很快.

这就是 MongoDB 的设计方式,将数据集加载到内存中的过程通常称为“预热”数据库,只有在预热之后(在您的情况下是第一个查询),您才能获得真正的性能。

值得注意的是,您的初始查询似乎仍然需要很长时间才能返回。您应该确保它有效地使用索引。该调查的最佳起点是explain()页面。

于 2012-02-20T15:08:21.480 回答
0

您可以使用db.collection.getPlanCache().clear()删除集合的所有缓存查询计划。

https://docs.mongodb.com/v3.2/reference/method/PlanCache.clear/

于 2017-12-19T16:17:04.097 回答