投影使查询更慢

Shr*_*ain 8 mongodb mongodb-query

我在MongoDb中有超过600k的记录.我的用户架构如下所示:

{
    "_id" : ObjectId,
    "password" : String,
    "email" : String,
    "location" : Object,
    "followers" : Array,
    "following" : Array,
    "dateCreated" : Number,
    "loginCount" : Number,
    "settings" : Object,
    "roles" : Array,
    "enabled" : Boolean,
    "name" : Object
}
Run Code Online (Sandbox Code Playgroud)

以下查询:

db.users.find(
     {},
     { 
         name:1, 
         settings:1,
         email:1,
         location:1
     }
).skip(656784).limit(10).explain()
Run Code Online (Sandbox Code Playgroud)

结果如下:

{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 10,
    "nscannedObjects" : 656794,
    "nscanned" : 656794,
    "nscannedObjectsAllPlans" : 656794,
    "nscannedAllPlans" : 656794,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 5131,
    "nChunkSkips" : 0,
    "millis" : 1106,
    "server" : "shreyance:27017",
    "filterSet" : false
}
Run Code Online (Sandbox Code Playgroud)

并删除投影相同的查询后 db.users.find().skip(656784).limit(10).explain()

结果如下:

{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 10,
    "nscannedObjects" : 656794,
    "nscanned" : 656794,
    "nscannedObjectsAllPlans" : 656794,
    "nscannedAllPlans" : 656794,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 5131,
    "nChunkSkips" : 0,
    "millis" : 209,
    "server" : "shreyance:27017",
    "filterSet" : false
}
Run Code Online (Sandbox Code Playgroud)

据我所知,投影总是会提高查询的性能.所以我无法理解为什么MongoDB的表现如此.有人可以解释一下吗.什么时候使用投影,什么时候不投影.以及如何在MongoDB中实现投影.

Ste*_*nie 5

您是正确的,投影使 MongoDB 2.6.3 中的此跳过查询变慢。这与跟踪为SERVER-13946的 2.6 查询规划器的优化问题有关。

2.6 查询计划器(如 2.6.3)在投影分析后添加 SKIP(和 LIMIT)阶段,因此投影被不必要地应用于在此查询的跳过期间被抛出的结果。我在 MongoDB 2.4.10 中测试了一个类似的查询,nScannedObjects结果等于 mylimit而不是skip + limit.

有几个因素会影响您的查询性能:

1) 您尚未指定任何查询条件 ( {}),因此此查询按自然顺序执行集合扫描,而不是使用索引。

2)查询无法覆盖,因为没有投影。

3) 你有一个非常大的skip值 656,784。

查询计划肯定有改进的余地,但我不希望这种幅度的跳过值在正常使用中是合理的。例如,如果这是一个分页的应用程序查询,每页有 50 个结果,那么您的skip()值将相当于页码 13,135。