我有一个带有以下索引的测试数据库:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "blogger.users"
},
{
"v" : 1,
"key" : {
"name" : 1,
"age" : 1
},
"name" : "name_1_age_1",
"ns" : "blogger.users"
},
{
"v" : 1,
"key" : {
"age" : 1,
"name" : 1
},
"name" : "age_1_name_1",
"ns" : "blogger.users"
}
]
运行以下查询时:
> db.users.find({"age":{"$gte":21,"$lte":30}})
.sort({"name":1})
.hint({"name":1,"age":1})
.explain()
我得到以下结果
{
"cursor" : "BtreeCursor name_1_age_1",
"isMultiKey" : false,
"n" : 83116,
"nscannedObjects" : 1000000,
"nscanned" : 1000000,
"nscannedObjectsAllPlans" : 1000000,
"nscannedAllPlans" : 1000000,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 7812,
"nChunkSkips" : 0,
"millis" : 1926,
"indexBounds" : {
"name" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"age" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"server" : "Johny-PC:27017",
"filterSet" : false
}
我多次运行此查询,nYield总是高于7k。没有任何其他进程更新,插入或删除数据。当我在没有提示的情况下运行相同的查询时,结果是相同的。
如果我使用其他索引作为提示运行相同的查询,则nYields为1200 +。
没有提示和排序它很快但是nYields:500+并使用另一个索引,正如预期的那样。
那么有没有办法找出为什么这么多的nYield存在,有人可以解释为什么会这样?
修改 一个简单的查找查询也有很多nYields。所以,问题不在于索引。我可能会遗漏一些东西。
答案 0 :(得分:3)
您强制查询在hint
调用时使用错误的索引,因为查询需要先按age
过滤,然后按name
排序。您告诉MongoDB使用的索引无法有效地用于此目的。
删除hint
来电或将其更改为:
db.users.find({"age":{"$gte":21,"$lte":30}})
.sort({"name":1})
.hint("age_1_name_1")
.explain()
查询需要扫描的文档越多(nscannedObjects
),它会产生读锁定的次数越多,因为它等待I / O完成以获取文档。因此查询效率越低,nYield就越高。 500+收益率没有任何问题,它只是意味着它是一个返回大量文档的查询(在这种情况下为83k)。