我有一个包含这些索引的集合:
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,
}
任何解决方案? 谢谢!
答案 0 :(得分:6)
您希望从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索引的更多信息,请参阅此处的优秀文章:
答案 1 :(得分:4)
它确实使用了一个索引 - 你可以判断,因为游标是一个BtreeCursor。您的收藏中有很多(10000)文件,其中包括“无名”文件。等于' Administrador'。
输出的解释:
"光标" :" Btree_Cursor nome_1"表示数据库在" nome"上使用了升序索引。满足查询。如果没有使用索引,则光标将是" BasicCursor"。
" nscanned" :数据库必须检查的文档数量(" nscannedObjects"对于此查询基本相同)
" N" :返回的文档数。这与" nscanned"相同的事实意味着索引是有效的 - 它不必检查任何与查询不匹配的文档。