【问题标题】:Why is this mongodb query so slow?为什么这个 mongodb 查询这么慢?
【发布时间】:2012-09-19 20:46:00
【问题描述】:

我有两个收藏,如下:

db.ships
文档格式:{ mmsi: Long, ...一些其他字段}
索引:{ {mmsi: 1}, {unique: true} }

db.navUpdates
文档格式:{ mmsi: Long, time: ISODate, ...一些其他字段}
索引:{ mmsi: 1 }, { time: 1 }

对于db.ships 中的每个文档,我需要在db.navUpdates 中找到与mmsi 匹配的最新文档。我无法使用_id 查找最新的文档,因为文档不一定按时间顺序(由时间戳time 定义)输入。

例如:

ship document:
{ mmsi: 12345 }

navUpdate documents:
{ mmsi: 12345, time: ISODate("2012-09-19T12:00:00.000Z") }
{ mmsi: 12345, time: ISODate("2012-09-18T12:00:00.000Z") }
{ mmsi: 54321, time: ISODate("2012-09-19T12:00:00.000Z") }

所以对于shipmmsi:12345,最新的navUpdate 是上面列表中的第一个文档,time:ISODate("2012-09-19T12:00:00.000Z")

我尝试了以下 mongo shell 脚本,但速度非常慢(仅 10 个查询需要几秒钟),而且messages appearing on the server indicate I'm missing an index

db.ships.find().limit(10).forEach(function(ship) {
    var n = db.navUpdates.find({mmsi:ship.mmsi}).count();
    if (n==0) { return; }
    var t = db.navUpdates.find({mmsi:ship.mmsi}).sort({time:-1}).limit(1)[0].time;
    print(t);
});

为什么这个查询这么慢?我尝试将{time: -1} 索引添加到navUpdate,认为sort({time: -1}) 可能是罪魁祸首,但仍然没有改善。

另外,这个查询可以优化吗?我在那里打了count() 电话,因为在navUpdates 中找不到一些ship 文档的mmsis。

【问题讨论】:

    标签: mongodb indexing


    【解决方案1】:

    单个查询只能使用一个索引,因此您应该在navUpdates 中添加一个复合索引{ mmsi: 1, time: -1 },以同时满足您的查找和排序需求。

    然后使用.explain() 确定您的索引是否在您的查询中使用。

    【讨论】:

    • 啊,所以必须遍历find({mmsi}) 返回的每个文档以检查其time 值,然后检查sort()ed。说得通。 sort({time:-1}) 能否利用带有{time:1} 的索引? (这个sort()的顺序重要吗?)
    • 回答我的评论:在这种情况下顺序无关紧要。当我sort({time:-1})explain()揭示了"cursor" : "BtreeCursor mmsi_1_time_1 reverse"的使用。
    猜你喜欢
    • 2011-03-11
    • 2020-03-19
    • 2014-03-12
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多