查询的执行时间—MongoDB



我有两个集合:coach和team。Coach集合包含有关教练的信息,如姓名、年龄和数组coached_Team,其中包含教练执教的球队的_id。团队集合包含关于球队的数据,如_id、通用名称、官方名称、国家、冠军....例如,如果我想找到Allegri执教过的所有球队的官方名称,我必须做两个查询,第一个是关于教练集合:

>var x = db.coach.find({surname:"Allegri"},{_id:0, "coached_Team.team_id":1})
>var AllegriTeams
>while(x.hasNext()) AllegriTeams=x.next()
{
    "coached_Team" : [
            {
                    "team_id" : "Juv.26
            },
            {
                    "team_id" : "Mil.74
            },
            {
                    "team_id" : "Cag.00
            }
    ]
}
>AllegriTeams=AllegriTeams.coached_Team
[
    {
            "team_id" : "Juv.26"
    },
    {
            "team_id" : "Mil.74"
    },
    {
            "team_id" : "Cag.00"
    }
]

然后我必须在team collection上执行三个查询:

> db.team.find({ _id:AllegriTeams[0].team_id}, {official_name:1,_id:0})
{official_name : "Juventus Football Club S.p.A."}
> db.team.find({ _id:AllegriTeams[1].team_id}, {official_name:1,_id:0})
{official_name : "Associazione Calcio Milan S.p.A"}
> db.team.find({ _id:AllegriTeams[2].team_id}, {official_name:1,_id:0})
{official_name:"Cagliari Calcio S.p.A"}

现在考虑我在收集团队和收集教练中有大约10万份文档。第一个查询(在coach收集上)需要大约71 ms加上while周期的时间。使用cursor.explain("executionStats")对团队集合进行的三个查询需要0毫秒。我不明白为什么这个查询需要0。我需要这三个查询中的executionTimeMillis来获得查询"查找由Allegri执教的所有球队的正式名称"的执行时间。我想将coach collection上查询的执行时间(71ms)与这三个查询的执行时间相加。如果这三个查询的时间都是0,我能说的主要是查询的执行时间吗?

我认为这里更重要的观察是,71ms对于一个项目的简单获取来说是很长的时间。看起来你的"姓氏"字段需要一个索引。其他"三个"查询是对主键的简单查找,这就是为什么它们相对较快的原因。

db.coach.createIndex({ "surname": 1 })

如果这个姓氏确实是"唯一的",那么也要加上:

db.coach.createIndex({ "surname": 1 },{ "unique": true })

您还可以通过简单地映射数组,并应用 $in 操作符,将"三个"查询简化为一个:

var teamIds = [];
db.coach.find(
    { "surname": "Allegri" },
    { "_id":0, "coached_Team.team_id":1 }
).forEach(function(coach) {
    teamIds = coach.coached_Team.map(function(team) {
        return team.team_id }).concat(teamIds);
    });
});
db.team.find(
    { "_id": { "$in": teamIds"  }},
    { "official_name": 1, "_id": 0 }
).forEach(function(team) {
    printjson(team);
});

当然,总体执行时间会大大降低,同时将多个操作的开销减少到只需要两个查询。

还要记住,不管执行计划统计中有什么,向服务器和从服务器发出的查询越多,发出每个请求和检索数据的总体实时执行时间就越长。因此,最好是保持尽可能少的东西。

因此,更合乎逻辑的是,定期"需要"此信息的地方,将"教练名称"存储在"团队本身"上(并对该数据进行索引)可以获得最快的响应,并且只需进行一次查询操作。

很容易陷入观察执行状态。但是,实际上,考虑什么是"最好"one_answers"最快"的模式,作为您想要执行的查询类型。

最新更新