2016-08-24 4 views
1

私は目標は、特定のカテゴリのトップ100(ソート)をフェッチすることで、このようなMongoDB:どのインデックスを使用しますか?

{username:"Bob",score:10,category:"mostLikes"} {username:"John",score:32,category:"mostLikes"} {username:"Bob",score:2,category:"leastDeaths"}

などのドキュメントが含まれているハイスコアMongoDBのテーブルを得ました。

重要:特定の上位カテゴリは昇順(低い方が良い例:leastDeaths)で、他は降順(大きい方が良い例:mostLikes)です。これは、カテゴリによっては、100の最も高いスコアまたは100の最も低いスコアのいずれかが欲しいことを意味します。

自分のアプリケーションに2つの主要なクエリがあります:あなたはどのようなインデックスをお勧めします

db.highscore.find({category:category}, {}).limit(100).sort({ score: 1 /*or -1*/ });

db.highscore.find({username:username});

は?

異なるテーブルに昇順カテゴリと降順カテゴリを維持すると、パフォーマンスが向上しますか?

注:カテゴリごとに1つのテーブルを持つことは望ましくありません。

+0

ちょっと@RainingChainあなたがこれが助けて納得したと思うなら、受け入れられた答えをマークしてください。 – user641887

答えて

2

私はいくつかのサンプルデータセットと私のローカル上でいくつかのテストを行なったし、私は最良の選択肢は、次のフィールドにインデックスを作成する「category_1_score_1_username_1」

にインデックスあなたのようにカバーされたクエリとを与えるを作成することだと思います文書は索引から直接戻されます。それがカバーされたクエリを返す作るために今、あなたは少しあなたのクエリを変更することができます

> db.usr.getIndexes(); 
     { 
       "v" : 1, 
       "key" : { 
         "category" : 1, 
         "score" : 1, 
         "username" : 1 
       }, 
       "name" : "category_1_score_1_username_1", 
       "ns" : "test.usr" 
     } 
] 
> 

は私の分析の下

> db.usr.find(); 
{ "_id" : ObjectId("57bd20630744bd376277a795"), "username" : "Bob", "score" : 10, "category" : "mostLikes" } 
{ "_id" : ObjectId("57bd20630744bd376277a796"), "username" : "John", "score" : 32, "category" : "mostLikes" } 
{ "_id" : ObjectId("57bd20630744bd376277a797"), "username" : "Bob1", "score" : 2, "category" : "leastDeaths" } 
{ "_id" : ObjectId("57bd20630744bd376277a798"), "username" : "John2", "score" : 132, "category" : "mostLikes" } 
{ "_id" : ObjectId("57bd20630744bd376277a799"), "username" : "Bob3", "score" : 20, "category" : "leastDeaths" } 
{ "_id" : ObjectId("57bd20630744bd376277a79a"), "username" : "John4", "score" : 132, "category" : "mostLikes" } 
{ "_id" : ObjectId("57bd20630744bd376277a79b"), "username" : "Bob5", "score" : 22, "category" : "leastDeaths" } 
{ "_id" : ObjectId("57bd20630744bd376277a79c"), "username" : "John6", "score" : 322, "category" : "mostLikes" } 
{ "_id" : ObjectId("57bd20630744bd376277a79d"), "username" : "Bob7", "score" : 232, "category" : "leastDeaths" } 
{ "_id" : ObjectId("57bd20630744bd376277a79e"), "username" : "John8", "score" : 3112, "category" : "mostLikes" } 
{ "_id" : ObjectId("57bd20630744bd376277a79f"), "username" : "Bob4", "score" : 222, "category" : "leastDeaths" } 
{ "_id" : ObjectId("57bd20630744bd376277a7a0"), "username" : "John22", "score" :, "category" : "mostLikes" } 
{ "_id" : ObjectId("57bd20630744bd376277a7a1"), "username" : "Bob33", "score" : 2111, "category" : "leastDeaths" } 

インデックスを検索します。

db.usr.find({"category":"mostLikes"},{"_id":0,"score":-1,"category":1,"username":1}).sort({"score":1}).explain("executionStats"); 

Output of Execution Stats: 

{ 
     "queryPlanner" : { 
       "plannerVersion" : 1, 
       "namespace" : "test.usr", 
       "indexFilterSet" : false, 
       "parsedQuery" : { 
         "category" : { 
           "$eq" : "mostLikes" 
         } 
       }, 
       "winningPlan" : { 
         "stage" : "PROJECTION", 
         "transformBy" : { 
           "_id" : 0, 
           "score" : -1, 
           "category" : 1, 
           "username" : 1 
         }, 
         "inputStage" : { 
           "stage" : "IXSCAN", 
           "keyPattern" : { 
             "category" : 1, 
             "score" : 1, 
             "username" : 1 
           }, 
           "indexName" : "category_1_score_1_username_1", 
           "isMultiKey" : false, 
           "isUnique" : false, 
           "isSparse" : false, 
           "isPartial" : false, 
           "indexVersion" : 1, 
           "direction" : "forward", 
           "indexBounds" : { 
             "category" : [ 
               "[\"mostLikes\", \"mostLikes\"]" 
             ], 
             "score" : [ 
               "[MinKey, MaxKey]" 
             ], 
             "username" : [ 
               "[MinKey, MaxKey]" 
             ] 
           } 
         } 
       }, 
       "rejectedPlans" : [ ] 
     }, 
     "executionStats" : { 
       "executionSuccess" : true, 
       "nReturned" : 7, 
       "executionTimeMillis" : 0, 
       "totalKeysExamined" : 7, 
       "totalDocsExamined" : 0, 
       "executionStages" : { 
         "stage" : "PROJECTION", 
         "nReturned" : 7, 
         "executionTimeMillisEstimate" : 0, 
         "works" : 8, 
         "advanced" : 7, 
         "needTime" : 0, 
         "needYield" : 0, 
         "saveState" : 0, 
         "restoreState" : 0, 
         "isEOF" : 1, 
         "invalidates" : 0, 
         "transformBy" : { 
           "_id" : 0, 
           "score" : -1, 
           "category" : 1, 
           "username" : 1 
         }, 
         "inputStage" : { 
           "stage" : "IXSCAN", 
           "nReturned" : 7, 
           "executionTimeMillisEstimate" : 0, 
           "works" : 8, 
           "advanced" : 7, 
           "needTime" : 0, 
           "needYield" : 0, 
           "saveState" : 0, 
           "restoreState" : 0, 
           "isEOF" : 1, 
           "invalidates" : 0, 
           "keyPattern" : { 
             "category" : 1, 
             "score" : 1, 
             "username" : 1 
           }, 
           "indexName" : "category_1_score_1_username_1", 
           "isMultiKey" : false, 
           "isUnique" : false, 
           "isSparse" : false, 
           "isPartial" : false, 
           "indexVersion" : 1, 
           "direction" : "forward", 
           "indexBounds" : { 
             "category" : [ 
               "[\"mostLikes\", \"mostLikes\"]" 
             ], 
             "score" : [ 
               "[MinKey, MaxKey]" 
             ], 
             "username" : [ 
               "[MinKey, MaxKey]" 
             ] 
           }, 
           "keysExamined" : 7, 
           "dupsTested" : 0, 
           "dupsDropped" : 0, 
           "seenInvalidated" : 0 
         } 
       } 
     }, 
     "serverInfo" : { 
       "host" : "L4156409", 
       "port" : 27017, 
       "version" : "3.2.5", 
       "gitVersion" : "34e65e5383f7ea1726332cb175b73077ec4a1b02" 
     }, 
     "ok" : 1 
} 
> 

このように、出力を見ることができるように、スキャンされたドキュメントの数は0で、レコードはインデックスから直接フェッチされます。したがって、このインデックスを選択すると、最初のクエリの最善の策になります。

2番目のクエリでは、ユーザー名フィールドにインデックスを作成するのが簡単で、2番目のクエリを解決する必要があります。

HTH。

関連する問題