3

我有这个文档结构:

{
  "key": {
    "a": Int32,
    "b": String
  }
}

在 和上具有唯一索引和key索引(非唯一)。key.akey.b

然而,这个查询扫描(慢):

{"key.a": 456213154}

而这个查询不会:

{"key": {
  "a": 456213154,
  "b": {"$exists": true}
}}

为什么这是必要的,应该是这样吗?

(我应该提到这是v2.0.3)

编辑:添加解释:

> db.collection.find({"key.a": 456213154}).explain()
{
        "cursor" : "BtreeCursor key.a_1",
        "nscanned" : 10962,
        "nscannedObjects" : 10962,
        "n" : 10962,
        "millis" : 20,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
                "key.a" : [
                        [
                                456213154,
                                456213154
                        ]
                ]
        }
}
> db.collection.find({"key": {"a": 456213154, "b": {"$exists":true}}}).explain()
{
        "cursor" : "BtreeCursor key_1",
        "nscanned" : 0,
        "nscannedObjects" : 0,
        "n" : 0,
        "millis" : 0,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
                "key" : [
                        [
                                {
                                        "a" : 456213154,
                                        "b" : {
                                                "$exists" : true
                                        }
                                },
                                {
                                        "a" : 456213154,
                                        "b" : {
                                                "$exists" : true
                                        }
                                }
                        ]
                ]
        }
}

编辑:我尝试删除两个非唯一索引 (key.a_1key.b_1) 以查看这是否可能会损害查询。不是:

> db.collection.find({"key.a": 456213154}).explain()
{
        "cursor" : "BasicCursor",
        "nscanned" : 23240518,
        "nscannedObjects" : 23240518,
        "n" : 10962,
        "millis" : 15047,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {

        }
}
4

1 回答 1

4

您的explain()输出表明:

  1. 有 10962 个对象具有key.a : 456213154. 您的db.collection.find({"key.a": 456213154})查询使用了 上的索引key.a,并返回了 10962 个对象。

  2. 您的集合中有 0 个对象具有key.a : 456213154key.b : { $exists : true }。该db.collection.find({"key": {"a": 456213154, "b": {"$exists":true}}})查询确实使用了您的索引索引。

查看n每个查询的值 - 这是返回的数字;和cursor值 - 这是BtreeCursor如果使用索引。在这种情况下,为什么第一个查询需要更长的时间是有道理的,因为它要返回的对象要多得多。

您确定具有值的文档key.a : 456213154也具有key.b值吗?

编辑:

带有$exists参数的查询是检查嵌入文档中存在的错误语法。

试试db.collection.find({ "key.a" : 456213154, "key.b" : { "$exists" : true } })

于 2012-10-11T16:38:34.173 回答