最初带有索引的快速查询如果在执行另一个慢查询后重复,则会慢得多



MongoDB, NodeJs with mongoose.我有一个包含 750 万份文档的大型数据库。有一个url字段,上面有一个索引{ url: 1 }

我的第一个查询是这样的:

Scheme.find({ url: { $regex: "^google.com.*" } }).limit(50).sort({ _id: -1 }).exec()
(the url values go without http/https, so it is a check for a values starts-with)

执行大约需要 0.04 秒。

好的,更进一步:现在搜索类似以下内容:

{ $regex: "^.*google.com.*" }

这花了 105 秒,因为正则表达式中字符串的开头是.*的,索引没有帮助。

好的,没关系。

但问题是: 现在我重复第一个查询(^google.com.*),搜索需要40-50秒

然后我只是重新启动mongod,它再次花费不到0.1秒

找不到这种行为的原因:(

也做了

Scheme.find({ url: { $regex: "^google.com.*" } }).limit(50).sort({ _id: -1 }).explain()

慢查询和快查询的结果没有差异,仅在result[0].executionStats.executionTimeMillis:快查询为 1

,慢查询结果为 15附言 服务器首次查询快速传递后的状态:https://gist.github.com/crystalbit/4e7919ddd822c0fbbf2dfc2bbad7195b

服务器第二次查询后的状态(法律上很慢):https://gist.github.com/crystalbit/6a3687784a6f982e3459bc400f2d26fb

服务器第三次查询后的状态(第一个查询的副本,预计很快,但速度很慢):https://gist.github.com/crystalbit/aff0381bf6b3f9ed35674ecb9f3ca1a1

许多数据库尝试缓存频繁查询或频繁访问的数据集。当然,这种"适应性"会导致相同查询的时间不同,因为缓存是有限的,可能会被新数据覆盖。 在某些数据库中,您可以更好地控制该过程,而在某些数据库中则更少。 MongoDB提供了一些控制,但看起来它更多地依赖于操作系统缓存。 FAQ:MongoDB Fundamental

下面是显式缓存的示例(查看"获取类别"部分)。 使用gen.engine重构龙卷风代码

最新更新