Mongodb查询使用点表示法缓慢

时间:2012-10-11 15:01:03

标签: mongodb

我有这个doc结构:

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

key上的唯一索引和key.akey.b上的索引(非唯一)。

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

{"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" : {

        }
}

1 个答案:

答案 0 :(得分: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}}})查询确实在密钥上使用了您的索引。

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

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

    编辑:

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

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