我的印象是覆盖查询总是比扫描集合本身更快。那么为什么这个覆盖查询速度较慢呢?
涵盖的查询:
> 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
}
最佳答案
请记住,索引覆盖的查询通常比常规查询更快,因为您可以一步检索每个文档的字段,而不是常规查询中的两步,在常规查询中,您需要点击索引来检索每个文档的字段。找到文档的位置,然后点击集合本身来检索字段。
稍微简化一下,在正常情况下,我的选择标准将检索 20000 个文档,正常查询将有 40000 次访问(索引 20000 次,集合 20000 次),而覆盖查询只有 20000 次访问。
但是,在您的测试用例中,您没有选择标准。因此,覆盖和未覆盖的查询都将进行完整的集合扫描。在这种情况下,您几乎失去了具有选择条件的覆盖查询的所有性能提升。
如果您确实想测试覆盖查询的值(value),我会使用更大的文档集合和更具选择性的查询。如果您使用的测试代表了您的实际生产使用情况,我根本不会期望任何性能提升。
关于mongodb - 为什么 MongoDB 中的覆盖查询有时会变慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23753346/