3

私はこのドキュメント構造を持っています:

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

に一意のインデックスがkeyあり、とにインデックス(一意ではない)がkey.aありkey.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
                                        }
                                }
                        ]
                ]
        }
}

編集:私は2つの一意でないインデックス(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 : 456213154db.collection.find({"key.a": 456213154})クエリは のインデックスを使用し、key.a10962 個のオブジェクトを返しました。

  2. あなたのコレクションにはkey.a : 456213154と を持っているオブジェクトがありませんkey.b : { $exists : true }。クエリはキーのdb.collection.find({"key": {"a": 456213154, "b": {"$exists":true}}})インデックスを使用しました。

n各クエリの値を参照してください。これは返される数値です。およびcursor値 - これはBtreeCursorインデックスが使用されている場合です。この場合、返されるオブジェクトが非常に多いため、最初のクエリに時間がかかる理由は理にかなっています。

key.a : 456213154値を持つドキュメントにも値があると確信していkey.bますか?

編集:

$existsparam を使用したクエリは、埋め込みドキュメント内の存在をチェックするための間違った構文です。

試してみてくださいdb.collection.find({ "key.a" : 456213154, "key.b" : { "$exists" : true } })

于 2012-10-11T16:38:34.173 に答える