7

これらのインデックスを持つコレクションがあります。

db.colaboradores.getIndexKeys()
[ { "_id" : 1 }, { "nome" : 1 }, { "sobrenome" : 1 } ]

とのようなクエリ

db.colaboradores.find({_id: ObjectId("5040e298914224dca3000006")}).explain();

それはインデックスでうまく機能します

{
    "cursor" : "BtreeCursor _id_",
    "nscanned" : 0,
    "nscannedObjects" : 0,
    "n" : 0,
    "millis" : 0,
}

しかし、実行すると:

db.colaboradores.find({nome: /^Administrador/}).explain()

mongodbはインデックスを使用しなくなりました:

{
    "cursor" : "BtreeCursor nome_1",
    "nscanned" : 10000,
    "nscannedObjects" : 10000,
    "n" : 10000,
    "millis" : 25,
}

解決策はありますか?ありがとう!

4

2 に答える 2

16

表示されている動作は、MongoDB から期待されます。これは通常、複数のフィールドを持つ複合インデックスを使用しているクエリに当てはまります。

経験則は次のとおりです。

{a:1, b:1, c:1} にインデックスがある場合、次のクエリでインデックスを効率的に使用できます。

find(a)
find(a,b)
find(a,b,c)
find(a).sort(a)
find(a).sort(b)
find(a,b).sort(b)
find(a,b).sort(c)

ただし、次のクエリではインデックスを十分に活用できません。

find(b)
find(c)
find(b,c)
find(b,c).sort(a)

その理由は、MongoDB が複合インデックスを作成する方法にあります。インデックスは btree であり、ノードはソートされた順序で btree に存在します。左端のフィールドがメジャー ソート、次のフィールドがセカンダリ ソート、というようになります。

インデックスの先頭メンバーをスキップすると、インデックス トラバーサルで多くのブロックをスキップする必要があります。そのパフォーマンスが遅い場合、クエリ オプティマイザーは、インデックスを使用するのではなく、フル コレクション スキャンを使用することを選択します。

MongoDB インデックスの詳細については、こちらの優れた記事を参照してください。

于 2012-08-31T17:55:37.350 に答える
4

インデックスを使用していました - カーソルが BtreeCursor だったのでわかります。あなたのコレクションには、'nome' が 'Administrador' に等しい大量 (10000) のドキュメントがあります。

出力の説明:

"cursor" : "Btree_Cursor nome_1" は、データベースがクエリを満たすために "nome" の昇順インデックスを使用したことを意味します。インデックスが使用されていない場合、カーソルは「BasicCursor」になります。

"nscanned" : データベースがチェックしなければならなかったドキュメントの数 ("nscannedObjects" は基本的にこのクエリと同じものです)

"n" : 返されたドキュメントの数。これが「nscanned」と同じであるという事実は、インデックスが効率的であることを意味します。クエリに一致しないドキュメントをチェックする必要はありませんでした。

于 2012-08-31T17:25:34.783 に答える