2

次のセカンダリ複合インデックスが埋め込まれています。

db.people.ensureIndex({"sources_names.source_id":1,"sources_names.value":1})

これは db.people.getIndexes() の一部です:

{
    "v" : 1,
    "key" : {
        "sources_names.source_id" : 1,
        "sources_names.value" : 1
    },
    "ns" : "diglibtest.people",
    "name" : "sources_names.source_id_1_sources_names.value_1"
}

したがって、次のインデックス カバー クエリを実行します。

db.people.find({ "sources_names.source_id": ObjectId('5166d57f7a8f348676000001'), "sources_names.value": "Ulrike Weiland" }, {"sources_names.source_id":1, "sources_names.value":1, "_id":0} ).pretty()
{
    "sources_names" : [
        {
            "value" : "Ulrike Weiland",
            "source_id" : ObjectId("5166d57f7a8f348676000001")
        }
    ]
}

5秒ほどかかりました。だから私は説明を実行します:

db.people.find({ "sources_names.source_id": ObjectId('5166d57f7a8f348676000001'), "sources_names.value": "Ulrike Weiland" }, {"sources_names.source_id":1, "sources_names.value":1, "_id":0 }).explain()
{
    "cursor" : "BtreeCursor sources_names.source_id_1_sources_names.value_1",
    "isMultiKey" : true,
    "n" : 1,
    "nscannedObjects" : 1260353,
    "nscanned" : 1260353,
    "nscannedObjectsAllPlans" : 1260353,
    "nscannedAllPlans" : 1260353,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 4,
    "nChunkSkips" : 0,
    "millis" : 4308,
    "indexBounds" : {
        "sources_names.source_id" : [
            [
                ObjectId("5166d57f7a8f348676000001"),
                ObjectId("5166d57f7a8f348676000001")
            ]
        ],
        "sources_names.value" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ]
    },
    "server" : "dash-pc.local:27017"
}

しかし、なぜこのインデックス カバー クエリがデータベース全体を通過するのでしょうか? パフォーマンスを向上させるには、どのようにインデックスを作成すればよいですか?

ありがとう!

4

1 に答える 1

0

ドキュメントsources_names.source_id(http://docs.mongodb.org/manual/tutorial/create-indexes-to-support-queries/#create-indexes-that-support-カバーされたクエリ):

次の場合、インデックスはクエリをカバーできません。

コレクション内のいずれかのドキュメントのインデックス付きフィールドのいずれかに配列が含まれています。インデックス付きフィールドが配列の場合、インデックスはマルチキー インデックス インデックスになり、カバーされたクエリをサポートできません。

これは説明からマルチキー インデックスであることがわかります。

"isMultiKey" : true,

基本的に、ドット表記はマルチキーとして分類されます。これsources_namesは、インデックスに配列が含まれているような配列であるためです。

速度の向上について:私はこれを調べていませんが、あなたの問題はここにあります:

"sources_names.value" : [
    [
        {
            "$minElement" : 1
        },
        {
            "$maxElement" : 1
        }
    ]
]

そのため、インデックスを検索するために最適に使用されていませんsources_names.value

編集

これはマルチキーインデックスであってはならないので、私が今与えた答えは少し奇妙だと思ったので、実際に行ってこれをテストしました:

> db.gh.ensureIndex({'d.id':1,'d.g':1})
> db.gh.find({'d.id':5, 'd.g':'d'})
{ "_id" : ObjectId("516826e5f44947064473a00a"), "d" : { "id" : 5, "g" : "d" } }
> db.gh.find({'d.id':5, 'd.g':'d'}).explain()
{
        "cursor" : "BtreeCursor d.id_1_d.g_1",
        "isMultiKey" : false,
        "n" : 1,
        "nscannedObjects" : 1,
        "nscanned" : 1,
        "nscannedObjectsAllPlans" : 1,
        "nscannedAllPlans" : 1,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 0,
        "indexBounds" : {
                "d.id" : [
                        [
                                5,
                                5
                        ]
                ],
                "d.g" : [
                        [
                                "d",
                                "d"
                        ]
                ]
        },
        "server" : "ubuntu:27017"
}

私の当初の考えでは、これはマルチキー インデックスであってはなりません。私の考えではいくつかの汚いデータがvalueあり、それが問題を引き起こしています。

私はあなたのデータベースを調べて、あなたの記録が正しく入力されていることを確認します。

あなたはおそらく次のようなものを持っています:

{
    "sources_names" : [
        {
            "value" : ["Ulrike Weiland", 1],
            "source_id" : ObjectId("5166d57f7a8f348676000001")
        }
    ]
}

どこか。

于 2013-04-12T15:03:04.690 に答える