我的印象是,覆盖的查询总是比扫描集合本身更快。那么为什么这个覆盖的查询更慢?
涵盖查询:
> db.group_panel_responses.find({}, {_id: 0, _panel_id: 1, _group_id: 1, response_count: 1}).hint({_panel_id: 1, _group_id: 1, response_count: -1}).explain()
{
"cursor" : "BtreeCursor _panel_id_1__group_id_1_response_count_-1",
"isMultiKey" : false,
"n" : 20000,
"nscannedObjects" : 0,
"nscanned" : 20000,
"nscannedObjectsAllPlans" : 0,
"nscannedAllPlans" : 20000,
"scanAndOrder" : false,
"indexOnly" : true,
"nYields" : 156,
"nChunkSkips" : 0,
"millis" : 44,
"indexBounds" : {
"_panel_id" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"_group_id" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"response_count" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
},
"server" : "DAAVID.local:27017",
"filterSet" : false
}
相同的查询,但没有暗示索引,所以不是一个被覆盖的查询:
> db.group_panel_responses.find({}, {_id: 0, _panel_id: 1, _group_id: 1, response_count: 1}).explain()
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 20000,
"nscannedObjects" : 20000,
"nscanned" : 20000,
"nscannedObjectsAllPlans" : 20000,
"nscannedAllPlans" : 20000,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 156,
"nChunkSkips" : 0,
"millis" : 40,
"server" : "DAAVID.local:27017",
"filterSet" : false
}
答案 0 :(得分:2)
请记住,索引所涵盖的查询通常比常规查询更快,因为您可以在一个步骤中检索每个文档的字段,而不是常规查询中的两个字段,您可以在其中查找索引找到文档的位置,然后点击集合本身以检索字段。
为了简化一点,在我的选择标准将检索20000个文档的正常情况下,正常查询将具有40000次访问(索引为20000,对于集合为20000),而覆盖查询将只有20000次访问。
但是,在您的测试用例中,您没有选择条件。因此,覆盖和未覆盖的两个查询都将执行完整的集合扫描。在这种情况下,您几乎可以通过选择标准丢失覆盖查询的所有性能提升。
如果您真的想测试覆盖查询的值,我会使用更大的文档集合和更具选择性的查询。如果您使用的测试代表您的实际生产用量,我根本不会期望任何性能提升。