【问题标题】:Sparse/Dense index and how does it work?稀疏/密集索引以及它是如何工作的?
【发布时间】:2017-11-08 03:21:38
【问题描述】:

我可以通过搜索树来了解 B*Tree 索引的工作原理。

但是,我不明白稀疏索引或密集索引是如何工作的。

例如,如果密集索引需要通过键映射每个值。当您进行搜索时,它将如何受益?

添加更多说明:
这个备用/密集索引指的是 wiki 上描述的索引: https://en.wikipedia.org/wiki/Database_index#Sparse_index

根据我的理解,索引的工作原理是您可以在 B*Tree 中搜索为 O(logN) 而不是搜索每个块为 O(N)

但是,从稀疏索引或密集索引的描述来看。 我看不出它对搜索有什么好处,你通过键搜索?但是,键的数量与值的数量相同吗? (对于密集索引,它是严格相等的)

我的猜测是密集索引和稀疏索引只是 B*Tree 中使用的索引。但是,我不确定我是否理解正确。因为,我在网上找不到任何东西来证实我的想法。

【问题讨论】:

  • 我预计这个问题要么是被 MongoDB 错误标记,要么是您将来自不同数据库的“稀疏/密集索引”概念混为一谈。假设您在 MongoDB 中引用 sparse indexes(与普通索引相反),索引机制的工作方式相同,但仅包含具有索引字段的文档。
  • 在 MongoDB 的 sparse index documentation 中有一条注释可能会有所帮助:“不要将 MongoDB 中的稀疏索引与其他数据库中的 block-level 索引混淆。将它们视为具有特定过滤器的密集索引。”
  • 您好,感谢您指出这一点。实际上,我将 MongoDB 中的稀疏索引与其他数据库中的块级索引混淆了。现在,我弄清楚了区别。但是,还是。我不明白稀疏/密集索引在其他数据库的块级索引中是如何工作的。
  • @Stennie 虽然我发现了区别。但是,我仍然无法弄清楚备用索引在 MongoDB 中是如何工作的。例如,您有 N 个值,其中字段 x 不为空。那么你将有 N 个键。那么密钥如何帮助您进行搜索呢?键是否必须是哈希(值)?否则,您需要搜索键,我认为搜索值是一样的。对吗?

标签: mongodb indexing b-tree database


【解决方案1】:

块级稀疏索引

块级稀疏索引仅对索引也是clustered 的查询有帮助(即索引的排序顺序表示磁盘上数据的位置)。块级稀疏索引将具有较少的值,但对于在开始顺序扫描之前找到大致位置仍然很有用。这种情况下的稀疏性实际上是“在聚集索引中索引每个第 n 个值”。

从搜索的角度来看,块级稀疏索引查询会:

  • 找到小于或等于索引搜索条件的最大键(正常B-tree Big O time complexity,即O(log N) 用于搜索)
  • 使用该键作为聚簇索引顺序扫描的起点(O(N) 用于搜索)

稀疏块级索引的优势主要在于大小而不是速度:较小的稀疏索引可能适合内存,而密集索引(包括所有值)则不能。对聚集索引的基于范围的查询已经会返回顺序结果,因此稀疏索引可能具有一些优势,只要索引不是太稀疏而无法有效地支持常见查询。

包含具有重复键的记录的聚集索引实际上是稀疏索引的一个示例:不需要使用相同值来索引每个单独记录的偏移量,因为聚集索引的逻辑顺序与索引的物理顺序匹配数据。

有关工作示例,请参阅:Dense and Sparse Indices (sfu.ca)。

带有sparse选项的MongoDB索引

我仍然无法弄清楚稀疏索引在 MongoDB 中是如何工作的。例如,您有 N 个值,其中字段 x 不为空。那么你将有 N 个键。那么密钥如何帮助您进行搜索呢?

带有sparse option 的 MongoDB 索引仅包含具有索引字段的文档的条目。 MongoDB 具有灵活的模式,因此集合中的所有文档不需要存在(或相同类型)字段。注意:可选 document validation 是 MongoDB 3.2+ 的一个特性。

默认情况下,集合中的所有文档都将包含在索引中,但那些不存在索引字段的文档将存储null 值。如果 MongoDB 集合中的所有文档都具有索引字段的值,则默认索引与使用 sparse 选项的索引没有区别。

这实际上是partial index 的一个特例:稀疏性是指将索引值的范围限制为仅包含非空条目。索引方法在其他方面与非稀疏索引相同。

MongoDB 文档用注释指出了这一点:

不要将 MongoDB 中的稀疏索引与其他数据库中的 block-level 索引混淆。将它们视为具有特定过滤器的密集索引。

【讨论】:

  • 感谢您的解释。块级稀疏索引仅对索引也是聚集的查询有帮助。这是消除我的困惑的地方。
  • 是否也需要对 MongoDB 索引进行聚类以使搜索受益?因此你只能有索引?
  • @user1947415 MongoDB(在 3.4 版本)没有聚集索引或您询问的更通用的“块级稀疏索引”。根据文档说明,将带有 sparse 选项的 MongoDB 索引视为具有特定过滤器的密集索引。您可以在 MongoDB 中为同一个集合拥有多个稀疏/部分索引;区别在于这些二级索引将仅包含与索引字段(带有sparse 选项的索引)或过滤器表达式(MongoDB 3.2+ 中的部分索引)匹配的文档条目。
  • 如果您在每个集合中有多个索引,那么当您分片时,您可以将数据仅排列到一个索引。 (就像聚集索引一样的想法)。在 MongoDB 中是如何处理的?
  • @user1947415 聚集索引控制数据在磁盘上的物理存储方式。分片是在分布式系统中对数据进行分区的高级概念(与您关于密集索引搜索与稀疏索引搜索的原始问题无关)。如果您对 MongoDB 概念还有其他疑问,我建议您在 DBA StackExchange 上发帖。
猜你喜欢
  • 2016-08-16
  • 2021-10-17
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 2018-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多