mongodb:如何将索引用于不同的命令和查询?

Rob*_*ert 5 indexing distinct mongodb

我对使用查询的非常慢的不同命令有一些问题。 根据我所观察到的,如果您未指定查询,则 distinct 命令仅使用索引

我在我的 MongoDB 3.0.10 服务器上用 1Mio 对象创建了一个测试数据库。每个对象如下所示:

{
    "_id" : ObjectId("56e7fb5303858265f53c0ea1"),
    "field1" : "field1_6",
    "field2" : "field2_10",
    "field3" : "field3_29",
    "field4" : "field4_64"
}
Run Code Online (Sandbox Code Playgroud)

字段值末尾的数字是随机的 0-99。

在集合上创建了两个简单索引和一个复合索引:

{ "field1" : 1 } # simple index on "field1"
{ "field2" : 1 } # simple index on "field2"
{                # compound index on all fields
    "field2" : 1,
    "field1" : 1,
    "field3" : 1,
    "field4" : 1
}
Run Code Online (Sandbox Code Playgroud)

现在我对该数据库执行不同的查询:

db.runCommand({ distinct: 'dbtest',key:'field1'})
Run Code Online (Sandbox Code Playgroud)

结果包含 100 个值,nscanned=100 并且它在“field1”上使用了索引。

现在相同的不同查询受到查询的限制:

db.runCommand({ distinct: 'dbtest',key:'field1',query:{field2:"field2_10"}})
Run Code Online (Sandbox Code Playgroud)

它再次包含 100 个值,但是 nscanned=9991 并且使用的索引是所有字段的第三个。

现在,最后一个查询中使用的第三个索引被删除。再次执行最后一个查询:

db.runCommand({ distinct: 'dbtest',key:'field1',query:{field2:"field2_10"}})
Run Code Online (Sandbox Code Playgroud)

它再次包含 100 个值, nscanned=9991 并且使用的索引是“field2”一个。

结论:如果我在没有查询的情况下执行不同的命令,结果将直接从索引中获取。但是,当我将不同的命令与查询结合使用时,只有查询使用索引,在这种情况下,不同的命令本身不使用索引。

我的问题是我需要在非常大的数据库上执行带有查询的不同命令。结果集非常大,但仅包含约 100 个不同的值。因此,完整的不同命令需要时间(> 5 分钟),因为它必须循环遍历所有值。

需要做什么来执行我上面介绍的可以由数据库直接从索引回答的独特命令?

Rob*_*ert 3

如果您的 Mongo 数据库版本支持,该索引将自动用于不同的查询。

在不同查询中使用索引的可能性需要 Mongo 版本 3.4 或更高版本 - 它适用于 MMAPv1/WiredTiger 两种存储引擎。

另请参阅错误票https://jira.mongodb.org/browse/SERVER-19507

  • 我不同意 - 问题是“我们如何在不同的查询中使用索引”,给出的答案是“升级到 Mongo 3.4”。您期望什么答案?该问题明确表明必要的索引已经存在。 (5认同)
  • 这并不能回答问题 (3认同)