MongoDB 索引的内部实现?

nit*_*ngh 4 indexing mongodb

我从这里学到了很多关于索引和查找内容的知识 。

索引支持在 MongoDB 中高效执行查询。如果没有索引,MongoDB 必须执行集合扫描,即扫描集合中的每个文档,以选择那些与查询语句匹配的文档。如果查询存在合适的索引,MongoDB 可以使用该索引来限制它必须检查的文档数量。

但我还有一些疑问:

  1. 使用(createIndex)创建索引时,记录是否始终存储在RAM中?
  2. 每次我的应用程序要重新启动时都需要创建索引吗?
  3. 在默认 id (_id) 的情况下会发生什么。始终存储在 RAM 中。
  4. _id 是默认索引,这意味着对于特定集合,所有记录始终存储在 RAM 中?

如果我错了,请帮助我。谢谢。

Rah*_*mar 10

我认为,您有一个想法,即索引存储在 RAM 中。如果我说他们不是怎么办。

首先我们需要了解什么是索引,索引基本上是一个指针,用于告诉该文档在磁盘上的位置。就像我们在书中有索引一样,为了更快地访问,我们可以看到哪个主题在哪个页码上。

因此,创建索引时,它们也存储在磁盘中,但是当应用程序运行时,基于频繁使用和更快的访问,它们会加载到 RAM 中,但加载和创建之间存在差异。

此外,加载索引与将集合或记录加载到 RAM 中不同。如果我们加载了索引,我们就知道要从磁盘中取出所有文档,这与加载所有文档并验证每个文档不同。所以索引避免了集合扫描。

索引的创建是一个一次性过程,但对文档的每次写入都可能会改变索引,因此某些部分可能需要重新计算,因为记录可能会根据数据的变化进行混洗。这就是索引使写入变慢而读取变快的原因。

再次将其视为一本书,如果您在书之间添加一个新主题,例如 2 页,则需要重新计算该主题编号之后的所有索引。因此。

使用(createIndex)创建索引时,记录是否始终存储在RAM中?。

  • 不,记录不存储在 RAM 中,在创建它时会处理集合中的所有文档并创建索引表,如果文档太多,这将是可以理解的耗时,这就是为什么可以选择在其中创建索引背景。

每次我的应用程序要重新启动时都需要创建索引吗?

  • 索引创建一次,您可以删除它并重新创建,但不会在应用程序或数据库重启时重新创建。对于分片环境中的大量收集来说,这将是疯狂的。

在默认 id (_id) 的情况下会发生什么。始终存储在 RAM 中。

  • 这又不是真的。_id 作为索引字段出现,因此已经为空集合创建了索引,因为当您执行 write 时,它​​会重新计算索引。由于它是唯一索引,因此处理速度会更快。

_id 是默认索引,这意味着对于特定集合,所有记录始终存储在 RAM 中?

  • 当您使用 MongoDB 的内存引擎时,所有记录只会存储在 RAM 中,我认为它是企业版。由于索引,它不会自动将记录加载到 RAM 中。

  • 如果你想在 mongod 启动时预热(上传到 RAM)你的索引,你可以使用 `db.runCommand({"touch" : <collection name>, "data" : true, "index" : true})`。访问不在内存中的索引条目的效率特别低,因为它通常会导致两个页面错误。将索引条目加载到内存中存在一个错误,然后将文档加载到内存中存在另一个错误。当索引查找导致页面错误时,它被称为 btree 未命中。MongoDB 还跟踪 btree 命中:当索引访问不必转到磁盘时(来自 MongoDB 权威指南)。 (2认同)