1

我们从“索引基数”视频 [M101J:面向 Java 开发人员的 MongoDB] 中学到的一件事是,当具有多键索引的文档被移动时,他的所有索引也必须更新,这会产生很大的开销。

我认为有可能以某种方式绕过这个约束。显而易见的解决方案是添加另一个间接级别(这是解决计算机科学问题的著名模式:-)),而不是直接从索引中引用文档,我们为每个引用该文档并获取索引的文档创建一个实体引用那个实体,现在当我们移动文档时,我们只需要修改那个实体(实体永远不会移动,因为它的 BSON 形状总是相同的)。这个解决方案的问题当然是用空间换性能(索引也有这个问题)。

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

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

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

谢谢

4

1 回答 1

1

这是我在发布与 Jira 票证相同的问题时从“Andy Schwerin”得到的答案:https ://jira.mongodb.org/browse/SERVER-12614

安迪·施未林回答:

  • 这是可行的,但它使所有读取都访问主索引。因此,如果您想读取通过二级索引找到的文档,则必须获取该 _id,然后在主索引中查找以找到当前位置。根据应用程序的不同,这可能是一个好的权衡,也可能是一个坏的权衡。过去的其他数据库系统在记录的旧位置(有时称为墓碑)中使用特殊标记来指向新位置。这使您仅在文档确实移动时才为间接付费,代价是需要定期清理索引以便您可以垃圾收集旧的墓碑。

还要感谢leif提供的信息链接http://www.tokutek.com/2014/02/the-effects-of-database-heap-storage-choices-in-mongodb/我问过作者同样的问题和这是他的回答:

Zardosht Kasheff 回答:

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