我认为稀疏索引是解决这个问题的答案,尽管您需要为每个字段创建一个索引。http://www.mongodb.org/display/DOCS/Indexes#Indexes-SparseIndexes
稀疏索引应该有助于 $exists:true 查询。
即使如此,如果您的字段不是真的稀疏(意味着它大部分是固定的),它也不会对您有太大帮助。
更新我想我错了。看起来有一个未解决的问题(https://jira.mongodb.org/browse/SERVER-4187)仍然 $exists 不使用稀疏索引。但是,您可以使用 find 和 sort 执行类似的操作,看起来它正确使用了稀疏索引:
db.ent.find({}).sort({a:1});
这是使用您的示例值的差异的完整演示:
> db.ent.insert({'a':5775, 'b':'b1'})
> db.ent.insert({'c':'its a c', 'b':'b2'})
> db.ent.insert({'a':7557, 'c':'its a c'})
> db.ent.ensureIndex({a:1},{sparse:true});
注意find({}).sort({a:1})
使用索引(BtreeCursor):
> db.ent.find({}).sort({a:1}).explain();
{
"cursor" : "BtreeCursor a_1",
"nscanned" : 2,
"nscannedObjects" : 2,
"n" : 2,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"a" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
并find({a:{$exists:true}})
进行全面扫描:
> db.ent.find({a:{$exists:true}}).explain();
{
"cursor" : "BasicCursor",
"nscanned" : 3,
"nscannedObjects" : 3,
"n" : 2,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
看起来您也可以使用 .hint({a:1}) 强制它使用索引。
> db.ent.find().hint({a:1}).explain();
{
"cursor" : "BtreeCursor a_1",
"nscanned" : 2,
"nscannedObjects" : 2,
"n" : 2,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"a" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}