2016-04-19 26 views
1

私はユーザー生成の投稿のコレクションを持っています。彼らは、次のフィールド可変クエリでMongoDBのインデックスを作成する

_id: String 
groupId: String // id of the group this was posted in 
authorId: String 
tagIds: [String] 
latestActivity: Date // updated whenever someone comments on this post 
createdAt: Date 
numberOfVotes: Number 
...some more... 

私のクエリは、常にこのような何かを見てが含まれてい...

Posts.find({ 
    groupId: {$in: [...]}, 
    authorId: 'xyz', // only SOMETIMES included 
    tagIds: {$in: [...]}, // only SOMETIMES included 
}, { 
    sort: {latestActivity/createdAt/numberOfVotes: +1/-1, _id: -1} 
}); 

だから私はいつものgroupIdを照会していますが、唯一時々tagIdsまたはユーザーIDを追加します。私はこれもソートされているフィールドを切り替えています。私の最高のインデックス作成戦略はどのように見えますか?

これまでここで読んできたことから、複数の複合インデックスを作成し、常に{groupId:1、_id:-1}で始めるようにしました。これらはすべてのクエリに含まれているため、良いプレフィックス候補。 ここでは、すべての可能な組み合わせについて新しいインデックスを作成することは、メモリを賢明に考える良い方法ではないと考えています。したがって、私はちょうどそのようにして、インデックスgroupIdと_idだけを保持する必要がありますか?

ありがとうございました。

+0

「複合インデックス」として '_id'を使用するのは実際には意味がありません。それは定義上「ユニーク」なので、他の可能なフィールドは何も差をつけることができません。いったん '_id'でマッチすれば、それだけです!他のキーの組み合わせについては、物事が一般的に使用される場合は、索引に追加する必要があります。 「接頭辞」は、常に一般的に使用されるものと、一致の数を最も減らすものの両方でなければなりません。あなたはどちらの組み合わせを使うべきですか?これは、あなたの質問が実際に何をしているのかの具体的な説明なしに、ここで尋ねるのが広い方法です。 –

+0

あなたが複合インデックスの最後の部分として_idを使用するのは、あなたがそれをソートしているからです。特に、それはタイムスタンプの2倍です。 – Onosa

答えて

0

あなたは正しい方向に向かっています。複合インデックスでは、最も選択的なインデックスが左側に、右側の範囲が右側に表示されます。 {groupId: 1, _id: -1}がこれを満たします。

複合インデックスは、キーが左から右のクエリ内にある場合に使用されることも覚えておくことも重要です。したがって、1つの複合インデックスは多くの一般的なシナリオをカバーできます。たとえば、インデックスが{groupId: 1, authorId:1, tagIds: 1}で、クエリがPosts.find({groupId: {$in: [...]},authorId: 'xyz'})だった場合、そのインデックスが使用されます(tagIdsが存在しなくても)。また、Posts.find({groupId: {$in: [...]},tagIds: {$in: [...]}})はこの索引を使用します(索引の最初と3番目のフィールドが使用されているため、Mongoによって特定された索引が見つからない場合は、この索引が使用されます)。ただし、Posts.find({authorId: 'xyz',tagIds: {$in: [...]}})は、索引の最初のフィールドが欠落していたため索引を使用しません。

これらのことを考えると、私は{groupId: 1, authorId:1, tagIds: 1, _id: -1}で始まることをお勧めします。 groupIdはクエリの唯一の非オプションフィールドです。したがって、オプションのフィールドの前には左に移動します。 authorIdはtagIdsよりも選択的なので、groupIdの後に左に移動する必要があります。あなたは_idでソートしていますので、右に行くべきです。データを照会するさまざまな方法については、必ずAnalyze Query performanceを確認してください。彼らがすべてこのインデックスを選択していることを確認してください(それ以外の場合は、さらに調整を加えるか、場合によっては2番目の複合インデックスを作成する必要があります)。その後、他の索引を作成して、それを使用してパフォーマンスに関するa-bテストを強制することができます。

+0

本当に助けてくれてありがとう。 authorIdとtagIdsがポジションを切り替えた別の複合インデックスを追加するのは意味がありませんか?または、追加のパフォーマンス上の利点は、メモリコストを補うものではありませんか? – proGrammar

+0

これに本当に答えるには、結果を比較して比較する必要があります。最初に両方のインデックスを個別に試してください。それから、コレクションの両方で同時に実行してみてください。 2つの化合物索引を持つことが単なる索引よりもはるかに優れている場合は、おそらくトレードオフの価値があります。私はあなたが見ると思いますが、1つのインデックスがほとんどのクエリに対して十分なパフォーマンスを発揮するということです。 – Onosa

関連する問題