【问题标题】:Mongodb aggregation pipeline optimization - 2 stage of $matchMongodb 聚合管道优化 - $match 的 2 阶段
【发布时间】:2019-06-10 15:00:28
【问题描述】:

我最近在研究聚合管道的性能优化。在决定要索引哪个时,我遇到了这个问题。我为 {'receiverId': 1,'type': 1 } 设置了一个复合索引。 我原来的管道是这样的。我正在考虑是否索引isRead 也是必要的。我之所以没有创建三字段复合索引是因为其他查询只使用了recieverIdtype

notifications.aggregate([{
        $match: {
            'recieverId': ObjectId(xxx),
            'type': xxx,
            'isRead': false
        }
    },
    {
     ...
    },
], (err, result) => {
    return res.status(200).json(result);
});

所以,我在下面改了这个。想知道这样的管道在过滤recieverIdtype 后是否可以节省一些计算成本。 isRead, 第二个 $match 是否会从第一个 $match 的结果中过滤?

notifications.aggregate([{
        $match: {
            'recieverId': ObjectId(xxx),
            'type': xxx,
        }
    },
    {
        $match: {
            'isRead': false
        }
    },
    {
     ...
    },
], (err, result) => {
    return res.status(200).json(result);
});

【问题讨论】:

    标签: mongodb aggregation-framework query-optimization


    【解决方案1】:

    实际上,您如何编写并不重要,因为 mongo 会优化此管道。

    来自文档:

    当一个 $match 紧跟另一个 $match 之后,这两个阶段可以合并为一个 $match。

    阅读有关它和其他管道优化 mongo 所做的here

    【讨论】:

    • 感谢链接,我读到了,我还在工作室 3T 中进行了管道测试,但仍在考虑是否创建包含 isRead 字段的复合索引,因为每当用户使用时,该值都会改变阅读。对上述查询有何建议?
    • isRead 字段添加到您的索引将有助于mongo,因为它不需要过滤它。这意味着它将有助于运行时。需要考虑的一件事(这对大多数人来说不是问题)是索引大小,在这种情况下应该不会有太大的不同。
    • 感谢,最后一个问题,例如,我总共有5个查询,前4个只查询recieverIdtype字段,只有最后一个查询三个字段recieverIdtype & `isRead',一个复合索引(3个字段)是否足以支持所有5个查询?
    • 是(取决于索引构建顺序),例如索引{x, y, z} 可以支持对xx,yx,y,z 的查询。也阅读了这个here
    猜你喜欢
    • 2019-06-03
    • 2015-04-24
    • 2020-07-09
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    相关资源
    最近更新 更多