首页 > 解决方案 > 使用高级查找时有什么改进缓慢的 mongodb 查询的策略?

问题描述

我已经构建了 3 个查询,我正在尝试优化其中一个,因为在我看来这是最好的方法。不幸的是,我没有得到我期望的表现。

最快查询: 仅简单查找,但您需要在最后阶段取消设置大量数据。想象一下,必须对 20 或 30 个您不想要的字段执行此操作。如果你使用 $project 你会弄乱 todos 集合数据,所以 unset 是唯一的方法。

我的数据集的执行时间是:176ms,我的数据集离场

db.todos
    .aggregate([
        {
            $lookup: {
                from: 'users',
                localField: 'user_id',
                foreignField: '_id',
                as: 'user',
            },
        },
        {
            $unwind: {
                path: '$user',
                preserveNullAndEmptyArrays: true,
            },
        },
        {
            $lookup: {
                from: 'user_data',
                localField: 'user.data_id',
                foreignField: '_id',
                as: 'user.data',
            },
        },
        {
            $unwind: {
                path: '$user.data',
                preserveNullAndEmptyArrays: true,
            },
        },
        { $unset: ['user._id', 'user.data_id', 'user.deleted', 'user.active', 'user.data._id'] },
    ])
    .explain();

我的最爱: 高级嵌套查找。我喜欢它,因为它干净清晰,但我不认为这个使用索引可能是因为使用了 $expr,即使它是在 _id 上完成的。

我的一组数据的执行时间是:713ms

db.todos
    .aggregate([
        {
            $lookup: {
                from: 'users',
                let: { user_id: '$user_id' },
                pipeline: [
                    { $match: { $expr: { $eq: ['$_id', '$$user_id'] } } },
                    {
                        $lookup: {
                            from: 'user_data',
                            let: { data_id: '$data_id' },
                            pipeline: [
                                { $match: { $expr: { $eq: ['$_id', '$$data_id'] } } },
                                { $project: { _id: 0, name: 1 } },
                            ],
                            as: 'data',
                        },
                    },
                    { $unwind: '$data' },
                    { $project: { _id: 0, email: 1, data: 1 } },
                ],
                as: 'user',
            },
        },
        {
            $unwind: {
                path: '$user',
                preserveNullAndEmptyArrays: true,
            },
        },
    ])
    .explain();

最糟糕的一个: 高级查找(非嵌套)。最慢的查询。我的一组数据的执行时间是:777ms

db.todos
    .aggregate([
        {
            $lookup: {
                from: 'users',
                let: { user_id: '$user_id' },
                pipeline: [
                    { $match: { $expr: { $eq: ['$_id', '$$user_id'] } } },
                    { $project: { _id: 0, email: 1, data_id: 1 } },
                ],
                as: 'user',
            },
        },
        {
            $unwind: {
                path: '$user',
                preserveNullAndEmptyArrays: true,
            },
        },
        {
            $lookup: {
                from: 'user_data',
                let: { data_id: '$user.data_id' },
                pipeline: [
                    { $match: { $expr: { $eq: ['$_id', '$$data_id'] } } },
                    { $project: { _id: 0, name: 1 } },
                ],
                as: 'user.data',
            },
        },
        {
            $unwind: {
                path: '$user.data',
                preserveNullAndEmptyArrays: true,
            },
        },
        { $unset: ['user.data_id'] },
    ])
    .explain();

我很惊讶(作为一名 Mongo 初学者)我考虑构建查询的方式并不是最有效的方式。有没有办法改进第二种选择,还是我坚持第一种?

待办事项

{"_id":{"$oid":"612156ec810895cfe9f406bd"},"user_id":{"$oid":"61214827810895cfe9f406ac"},"title":"todo 1"}

一个用户

{"_id":{"$oid":"61216d36810895cfe9f40713"},"active":true,"deleted":false,"data_id":{"$oid":"61216d42810895cfe9f40716"},"email":"test2@test2.com"}

用户数据

{"_id":{"$oid":"6121488f810895cfe9f406ad"},"name":{"first":"Fanny","last":"Lenny"}}

谢谢

标签: mongodbmongodb-query

解决方案


推荐阅读