MongoDB的投影查询有多高效?

13

在查询Mongo数据库时,如果排除文档中几乎所有的数据,会不会存在很多开销?

例如,如果我只想要一个具有以下结构的集合中的field1field2

{
    "field1" : 1
    "field2" : true
    "field3" : ["big","array",...]
    "field4" : ["another","big","array",...]
}

我会从哪一个方面受益更多:

  1. 创建一个与该集合并列的新集合,其中只包含field1和field2,或者
  2. 在原始文档上使用带有包含/排除参数的.find()方法

注意:对我来说,将相同数据保存两次的低效并不是最重要的问题,相对重要的是查询数据的效率。

非常感谢!


这些文档有多大? - Asya Kamsky
大约每个文件大小为0.3MB,field1和field2的组合小于1kB。文件大小会有影响吗? - Ash
查询文档时,整个文档可能会全部加载到内存中,即使您只需要其中的某些特定字段,因此这将影响文档占用的RAM大小。您想要的两个字段总是前两个字段吗? - Asya Kamsky
@AsyaKamsky 是的,始终是前两个字段,它们的组合大小始终远小于整个文档的大小。 - Ash
1个回答

8
投影与在SQL中显式使用列名有些相似,因此询问返回较少的数据是否会比返回更多的数据(完整文档)产生开销似乎有点违反直觉。

因此,你需要找到文档(取决于你如何查找find()可能快也可能慢),但是只返回文档的前两个字段而不是所有字段(完整文档)会使它更快而不是更慢。

如果你担心集合适合放入RAM,则拥有第二个集合可能仅有益处。如果副本集合中的文档要小得多,则它们可以假定适合于较小总RAM,从而减少了页面需要从磁盘交换的机会。然而,如果你也要写入这个集合和原始集合,那么你必须在RAM中拥有比只有原始集合更多的数据。

因此,虽然复杂的细节可能取决于你的个人设置,但一般答案可能是2.你将受益于使用投影并仅返回你需要的两个字段。


非常感谢您提供如此详细的答案!我还有一个问题,如果我在field1和field2上建立索引,并在这两个字段上查询集合的子集,那么这样做是否只会将该数据子集加载到RAM中?对于数据库方面我了解不多,敬请谅解。 - Ash
1
只有包含所需文档的页面才会加载到RAM中。当然,索引也将存储在RAM中。 - Asya Kamsky
你真的确定这个答案吗?MongoDB存储整个文档,而不是列,因此需要过滤掉不需要的字段似乎是一个额外的操作,会减慢查询速度(除了覆盖查询的情况)。 - Juan Perez
是的,我对答案非常有把握。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接