2

これは私がクエリしたい私のドキュメントです:

{
"_id":ObjectId("5062d30522dfae0e11000000"),
"id_resource" : "147",
"moment_created" : ISODate("2012-03-22T16:29:21Z"),
"moment_updated" : ISODate("2012-03-22T16:29:21Z"),
"users_involved" : [
    {
        "id_user" : "113928869",
        "state" : "answered",
        "id_folder" : "0",
        "is_deleted" : "0"
    },
    {
        "id_user" : "121624627",
        "state" : "new",
        "id_folder" : "0",
        "is_deleted" : "0" }
],
"posts" : [
    {
        "id_author" : "113928869",
        "post" : "hiohhio",
        "moment_created" : ISODate("2012-03-22T16:29:21Z")
    }
    ]
}

これが私のインデックスを確実にしようとした方法です:

db.message.ensureIndex({id_resource:1, users_involved : 1});

これは、コレクションのクエリに使用したクエリです。

db.message.find({id_resource : "143", "users_involved" : {$elemMatch : {id_user : "101226353", state : "answered"}}});

しかし、後で説明する1つは、この出力を取得します。

{
    "clusteredType" : "ParallelSort",
    "cursor" : "BasicCursor",
    "n" : 11,
    "nChunkSkips" : 0,
    "nYields" : 8624,
    "nscanned" : 1461277,
    "nscannedAllPlans" : 1461277,
    "nscannedObjects" : 1461277,
    "nscannedObjectsAllPlans" : 1461277,
    "millisShardTotal" : 1878,
    "millisShardAvg" : 939,
    "numQueries" : 2,
    "numShards" : 2,
    "millis" : 1646

}

getIndexesは以下を返します:

[
    {
            "v" : 1,
            "key" : {
                    "_id" : 1
            },
            "ns" : "messaging.message",
            "name" : "_id_"
    },
    {
            "v" : 1,
            "key" : {
                    "id_resource" : 1,
                    "users_involved" : 1
            },
            "ns" : "messaging.message",
            "name" : "id_resource_1_users_involved_1"
    }

]

残念ながら、クエリでインデックスid_resource_1_users_involved_1が使用されていない理由がわかりません。インデックスが使用されない理由や、使用したいクエリをサポートするためにインデックスを作成する方法を誰かに説明してもらえますか?

時間と助けのためのthx

アップデート

私の恥、私の側のタイプミス。これがクエリの実際の説明です

{
    "clusteredType" : "ParallelSort",
    "cursor" : "BtreeCursor id_resource_1_users_involved_1",
    "n" : 5,
    "nChunkSkips" : 0,
    "nYields" : 2,
    "nscanned" : 46868,
    "nscannedAllPlans" : 93736,
    "nscannedObjects" : 46868,
    "nscannedObjectsAllPlans" : 93736,
    "millisShardTotal" : 281,
    "millisShardAvg" : 140,
    "numQueries" : 2,
    "numShards" : 2,
    "millis" : 220

}

クエリは私のインデックスを使用していますが、それでも遅いです。また、nscannedはかなり大きいので、インデックス全体が使用されていませんか?nscannedがリソースxのメッセージの量と一致するかどうかを確認する必要があります

JohnnyHKの複合インデックスを使用すると、はるかに高速になりました。

ensureIndex({id_resource:1, 'users_involved.id_user':1, 'users_involved.state':1});

説明

{
    "clusteredType" : "ParallelSort",
    "cursor" : "BtreeCursor id_resource_1_users_involved.id_user_1_users_involved.state_1",
    "n" : 5,
    "nChunkSkips" : 0,
    "nYields" : 0,
    "nscanned" : 7,
    "nscannedAllPlans" : 7,
    "nscannedObjects" : 7,
    "nscannedObjectsAllPlans" : 7,
    "millisShardTotal" : 0,
    "millisShardAvg" : 0,
    "numQueries" : 2,
    "numShards" : 2,
    "millis" : 1
}

したがって、users_involved配列をクエリする場合は、クエリごとに個別のインデックスを作成する必要がありますか?

また、@ JohnnyHKは、次のように配列全体を使用します。

find({id_resource : "197", "users_involved" : {$elemMatch : {id_user : "128825371", state : "answered", id_folder:"0", is_deleted:"0"}}}).hint("id_resource_1_users_involved_1")

何も改善しなかった、説明する:

{
    "clusteredType" : "ParallelSort",
    "cursor" : "BtreeCursor id_resource_1_users_involved_1",
    "n" : 5,
    "nChunkSkips" : 0,
    "nYields" : 1,
    "nscanned" : 46868,
    "nscannedAllPlans" : 46868,
    "nscannedObjects" : 46868,
    "nscannedObjectsAllPlans" : 46868,
    "millisShardTotal" : 222,
    "millisShardAvg" : 111,
    "numQueries" : 2,
    "numShards" : 2,
    "millis" : 174

}

または多分私はまだそれを間違っていますか?

*また、説明の応答からシャード情報を削除しました。この情報が重要である可能性がある場合は、そのように言ってください

4

1 に答える 1

1

複合インデックスにはusers_involved配列全体が含まれるため、インデックスは、配列の完全な埋め込みドキュメント要素と一致する場合にのみ使用できます。ここを参照してください。

users_involved検索しようとしているフィールドだけを含む複合インデックスを使用した方がよいと思います。だからどちらか:

db.message.ensureIndex({id_resource:1, 'users_involved.id_user' : 1});

また

db.message.ensureIndex({id_resource:1, 'users_involved.id_user' : 1, 'users_involved.state' : 1});
于 2012-10-08T13:52:33.993 に答える