mongodb - 使用高级查找时有什么改进缓慢的 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"}}
谢谢
解决方案
推荐阅读
- javascript - 如何设置对象的初始状态 Redux 数组(图像信息列表)
- android - 如何使用 ViewPager、TabLayout 和 RecyclerView 并禁用 ViewPager 滑动?
- oracle - 错误 manager.SqlManager:错误执行语句:java.sql.SQLException:指定的 Oracle URL 无效
- javascript - 在页面中的多个表单上实施 reCAPTCHA v3
- apache - 是否可以使用 Apache 或 Nginx 重写 SOAP POST 请求主体?
- reactjs - 如何在关闭浏览器时将讨厌的 redux 状态清除到本地存储?
- redux-saga - 当 promise 解决时,redux-saga 调用不会产生。这里会发生什么?
- angular - 在 Angular 6 中使用默认属性输入
- django - 带有断线和重定向 url 的 Django 消息
- javascript - 如何确保在输入类型=密码时立即发生值屏蔽,而不会在电话上延迟?