mongodb - 复合索引的顺序在 MongoDB 性能方面有何影响?

标签 mongodb indexing compound-index

我们需要以与查询参数相同的顺序创建复合索引。这个顺序对性能有影响吗?

想象一下,我们有一个地球上所有人类的集合,其中有一个关于 sex 的索引(99.9% 的时间是“男性”或“女性”,但仍然是字符串(不是二进制))和一个索引关于名称

如果我们希望能够选择具有特定 name 的特定 sex 的所有人,例如所有名为 “John” 的“男性”,最好先使用 sex 还是先使用 name 的复合索引?为什么(不)?

最佳答案

雷德桑德罗,

你必须考虑 Index Cardinality Selectivity


1。索引基数

索引基数是指一个字段有多少个可能的值。 sex 字段只有两个可能的值。它具有非常低基数姓名、用户名、电话号码、电子邮件等其他字段对于集合中的每个文档都将具有更独特的值,这被认为是高基数

  • 更大的基数

    字段的基数越大,索引就越有用,因为索引缩小了搜索空间,使其成为一个更小的集合。

    如果您有关于 sex 的索引,并且您正在寻找名叫 John 的男性。如果您首先按 sex 进行索引,您只会将结果空间缩小大约 %50。相反,如果您按 name 进行索引,您会立即将结果集缩小到一小部分名为 John 的用户,然后您将引用这些文档来检查性别。

  • 经验法则

    尝试在 high-cardinality 键上创建索引,或者将 high-cardinality 键放在复合索引的首位。您可以在本书的复合索引部分了解更多信息:

    MongoDB The Definitive Guide


2。选择性

另外,您想使用索引 selectively并编写查询以限制具有索引字段的可能文档的数量。为简单起见,请考虑以下集合。如果你的索引是 {name:1},如果你运行查询 { name: "John", sex: "male"}。您必须扫描 1 文件。因为您允许 MongoDB 具有选择性。

{_id:ObjectId(),name:"John",sex:"male"}
{_id:ObjectId(),name:"Rich",sex:"male"}
{_id:ObjectId(),name:"Mose",sex:"male"}
{_id:ObjectId(),name:"Sami",sex:"male"}
{_id:ObjectId(),name:"Cari",sex:"female"}
{_id:ObjectId(),name:"Mary",sex:"female"}

考虑以下集合。如果你的索引是 {sex:1},如果你运行查询 {sex: "male", name: "John"}。您必须扫描 4 个文档。

{_id:ObjectId(),name:"John",sex:"male"}
{_id:ObjectId(),name:"Rich",sex:"male"}
{_id:ObjectId(),name:"Mose",sex:"male"}
{_id:ObjectId(),name:"Sami",sex:"male"}
{_id:ObjectId(),name:"Cari",sex:"female"}
{_id:ObjectId(),name:"Mary",sex:"female"}

想象一下更大数据集上可能存在的差异。


复合索引的一点解释

很容易对复合索引做出错误的假设。根据MongoDB docs on Compound Indexes .

MongoDB supports compound indexes, where a single index structure holds references to multiple fields within a collection’s documents. The following diagram illustrates an example of a compound index on two fields:

enter image description here

当您创建复合索引时,1 个索引 将包含多个字段。因此,如果我们通过 {"sex": 1, "name": 1} 对集合进行索引,则索引大致如下:

["male","Rick"] -> 0x0c965148
["male","John"] -> 0x0c965149
["male","Sean"] -> 0x0cdf7859
["male","Bro"] ->> 0x0cdf7859
...
["female","Kate"] -> 0x0c965134
["female","Katy"] -> 0x0c965126
["female","Naji"] -> 0x0c965183
["female","Joan"] -> 0x0c965191
["female","Sara"] -> 0x0c965103

如果我们通过 {"name": 1, "sex": 1} 对集合进行索引,则索引大致如下:

["John","male"] -> 0x0c965148
["John","female"] -> 0x0c965149
["John","male"] -> 0x0cdf7859
["Rick","male"] -> 0x0cdf7859
...
["Kate","female"] -> 0x0c965134
["Katy","female"] -> 0x0c965126
["Naji","female"] -> 0x0c965183
["Joan","female"] -> 0x0c965191
["Sara","female"] -> 0x0c965103

{name:1} 作为 Prefix在使用复合索引时会更好地为您服务。关于这个主题还有更多可以阅读的内容,我希望这可以提供一些清晰的信息。

关于mongodb - 复合索引的顺序在 MongoDB 性能方面有何影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33545339/

相关文章:

node.js - 设置 node.js 数据库 MongoDB/Redis 的最佳方式?

node.js - 如何在 Node 中的 MongoDB 更新中返回完整文档

indexing - 如何创建和维护 couchDB/pcouchDB doc _id

javascript - 在 IndexedDB 中搜索复合索引

javascript - 返回干净 json 对象的快速路由

sql - 对于整数类型的主键,为什么避免间隙很重要?

indexing - 建立索引后,Sitecore 文档字段为空

mongodb - _rperm 的 parse 中的索引方法

sql - 优化 SQL 查询以避免全表扫描

node.js - 使用 mongoose 验证整数值