0

私はmongodbでこれに使用するのに最適なインデックスを見つけようとしています:

db.articles.find({"images.url":{"$exists":true}, \  
    "source_id": {"$in":[ObjectId("511baf3aa56bde8e94000002"), ObjectId("511baf3aa56bde8e94000999")]}})  \
    .sort({"published_at": -1})

images.url が存在する記事のみを含めたいので、スパース インデックスになるかどうか疑問に思っています。また、次のさまざまなポインターを読んだため、どのフィールドを順番にインデックス付けするかわかりません。

  1. まず、正確な値を照会するフィールド。("images.url": 存在)
  2. 次に、ソートするフィールドです。(:published_at)
  3. 最後に、値の範囲を照会するフィールドです。(source_id)

また、上記の例では、source_id が値の範囲になるかどうかわかりません。

私が考えていた:

index "images.url": -1, published_at: -1, source_id: 1, {sparse: true}

しかし、私はインデックスの排他性を最大化することにも悩んでいるので、次のことを検討しています:

index source_id: 1, "images.url": -1, published_at: -1, {sparse: true}
4

1 に答える 1

4

このようなコレクションがあれば

{ a:1, b:1, c:1 }
{ a:1, b:1, c:2 }
{ a:1, b:1, c:3 }
{ a:1, b:2, c:1 }
... // all permutations up to:
{ a:3, b:3, c:3 }

このコレクションをランダムな順序で想像してみてください

({a:1,b:1,c:1}) の複合インデックスは次のようになります。

a:  |        1        |        2        |        3        |
    |-----------------+-----------------+-----------------|                   
b:  |  1  |  2  |  3  |  1  |  2  |  3  |  1  |  2  |  3  |
    |-----+-----+-----+-----+-----+-----+-----+-----+-----|
c:  |1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|1|2|3|

それぞれの a に対して、そのすべての b とそのすべての c が順番にありますね。

クエリ: db.xx.find({a:2}).sort({b:1})の場合、b 要素が a=2; の下にあることがわかります。インデックスは並べ替えに使用されます - "scanAndOrder" : Explain() でfalse クエリがdb.xx.find({a:2,c:{$in:[1,3]}}).sort({b:1})の場合、同じことが起こります。

しかし、これ: db.xx.find({a:{$in:[1,3]}}).sort({b:1}).explain()は"scanAndOrder" : trueを教えてくれます。 index はソートには使用されませんでした (クエリには使用されました) - 上記のスキーマからわかるように、a=[1,3] の "b" は連続していません。

そのため、インデックスの効率的なシーケンスは次のとおりです。

(1) exact matches (only one!)
(2) sort criteria
(3) matches that point to more than one document

あなたの場合、完全に一致するものはありません。どちらのクエリも、複数のドキュメントを返します。例でこれを試してみましょう。

db.xx.find({a:{$in:[1,3]},b:{$in:[1,3]}}).sort({c:1}).explain():を使用しますクエリにはインデックスを使用しますが、並べ替えには使用しないため、15 をスキャンして 12 個のオブジェクトを返します。

db.xx.find({b:{$in:[1,3]},c:{$in:[1,3]}}).sort({a:1}).explain():を使用しますクエリと並べ替えにはインデックスを使用しますが、21 をスキャンして 12 個のオブジェクトを返します。

どちらの方がよいですか?ユースケースによって異なります。通常、検索で多くのドキュメントが返される場合は、並べ替えでインデックスを使用する方が効率的ですが、(多数の中から) 少数しか返されない場合は、より効率的なスキャンを使用することをお勧めします。試してみて、explain() を使用して何が優れているかを確認してください

これは役に立ちますか?

よろしく

ロナルド

PS私はこれを使用してサンプルコレクションを作成しました:

[1,2,3].forEach(function(a){
    [1,2,3].forEach(function(b){
        [1,2,3].forEach(function(c){
            db.xx.insert({a:a,b:b,c:c});
        })
    })
})
于 2013-03-21T12:26:41.467 に答える