3

我非常熟悉 MongoDB 中的缓存是如何与操作系统的内存映射文件相关的。但是,我对它的细节更感兴趣...

假设,我在一个集合中有这种格式的文档:

{
  _id: ObjectId("..."),
  first_name: "x",
  last_name: "y",
  email: "z"
}
  1. 如果findOne({_id: ObjectId("...")})执行命令,则整个文档将被放入缓存中。在此之后,如果我运行findOne({_id: ObjectId("...")}, {email: 1}),是否会使用缓存(请注意,在最后一个命令中,我只对电子邮件字段感兴趣)?

  2. 如果我发出findOne({_id: ObjectId("...")}, {first_name: 1, last_name: 1}),是整个文档都放入缓存,还是只是投影字段?也就是说,如果我findOne({_id: ObjectId("...")})在前面的命令之后运行,会不会用到缓存呢?

谢谢,
兹拉特科

4

1 回答 1

2

除非您的查询仅由索引满足(即使用覆盖索引),否则任何加载部分文档的操作都会将整个内容分页到内存中。因此,当您重新运行并更改返回的字段时,文档将在缓存中。

使用投影来限制某些字段只是意味着它不会返回您未指定的字段(因此它在返回的数据方面更有效,特别是如果您有未使用的大字段)。

注意:您的问题让我想到了跨越多个页面的文档,以及是否会有所作为——我需要研究/测试的东西,这可能很有趣。

但是,严格来说,放入缓存的内容不仅仅取决于文档或正在使用的索引。 预读也将发挥作用(至少对于 Linux 而言),无论您的文档大小如何,您都将阅读完整的 4k 页,因此那里可能存在效率低下的因素。具体多少取决于您的文档大小和碎片程度。更多关于该主题的讨论可以在这里找到:

https://serverfault.com/questions/408100/mongodb-and-datasets-that-dont-fit-in-ram-no-matter-how-hard-you-shove/408182#408182

于 2012-12-03T08:21:26.403 回答