加强MongoDB索引的建议

加强MongoDB索引的建议,mongodb,mongodb-indexes,Mongodb,Mongodb Indexes,我们从“Index Cardinality”视频[M101J:MongoDB for Java Developers]中学到的一点是,当一个具有多键索引的文档被移动时,他的所有索引也必须被更新,这会产生很大的开销 我曾认为有可能以某种方式绕过这个限制。显而易见的解决方案是添加另一个间接层次(这是解决计算机科学问题的著名模式:-)),而不是直接从索引引用文档,我们为引用该文档的每个文档创建一个实体,并获取引用该实体的索引,现在,当我们移动文档时,我们只需修改该实体(该实体永远不会移动,因为其BSO

我们从“Index Cardinality”视频[M101J:MongoDB for Java Developers]中学到的一点是,当一个具有多键索引的文档被移动时,他的所有索引也必须被更新,这会产生很大的开销

我曾认为有可能以某种方式绕过这个限制。显而易见的解决方案是添加另一个间接层次(这是解决计算机科学问题的著名模式:-)),而不是直接从索引引用文档,我们为引用该文档的每个文档创建一个实体,并获取引用该实体的索引,现在,当我们移动文档时,我们只需修改该实体(该实体永远不会移动,因为其BSON形状始终相同)。当然,这种解决方案的问题在于以交易空间换取表现(指数也面临这一问题)

但所有的希望都没有丧失;在MongoDB中,所有文档都有一个不可变的_id字段,该字段将自动编制索引。考虑到所有这些,我们知道如果文档被移动,其关联的_id索引也将被更新,那么为什么不让所有其他索引引用文档的相应_id索引呢

给定此解决方案,文档移动时唯一会更新的索引是_id索引

我想知道这个解决方案是否可以在MongoDB中实现,或者是否有一些隐藏的陷阱使得它变得不切实际


谢谢

以下是我从“Andy Schwerin”那里得到的答案,当时我发布了与Jira门票相同的问题:

Andy Schwerin回答:

  • 这是可行的,但它使所有读取访问主索引。因此,如果您想阅读通过二级索引找到的文档,您必须获取该_id,然后在主索引中查找它以找到当前位置。根据应用程序的不同,这可能是一个好的折衷方案,也可能是一个坏的折衷方案。过去,其他数据库系统在记录的旧位置使用特殊标记,有时称为墓碑,以指向新位置。这样,您就可以仅在文档确实移动时支付间接寻址费用,而需要定期清理索引,以便对旧墓碑进行垃圾收集
同样感谢leif提供的信息链接,我向作者提出了同样的问题,以下是他的答案:

Zardosht Kasheff回答:

  • 可以,但是对二级索引的点查询可能会导致三个I/O而不是两个I/O。目前,无论使用哪种方案,对二级索引的点查询都可能需要一个I/O来获取行标识符,另一个I/O来检索文档。使用此方案,需要一个I/O来获取_id,另一个I/O来获取行标识符,第三个I/O来获取文档。这似乎不可取

这看起来像是发布在jira.mongodb.org或某个mongo讨论列表上的东西。这不需要加载BSON文档来检查索引吗?这正是我们在TokuMX(一个具有改进存储的mongodb发行版)中所做的,我的同事实际上刚刚在这里写到: