mongodb语法$vlookup性能分析

1 场景描述

mongodb有两个表department和user表,

department表有_id,name,level,表有记录169w条

user表有_id,name,department_id,表有记录169w条,department_id没有创建索引,department_id是department的_id。

现在需要写个vlooup方法,查询level下面有多少用户。

2 user表$vlookup表department写法

cpp 复制代码
db.user.aggregate([
  // 连接 department 表获取 level 信息
  {
    $lookup: {
      from: "department",       // 关联的目标表
      localField: "department_id", // user 表的关联字段
      foreignField: "_id",      // department 表的关联字段
      as: "dept"                // 关联结果的别名
    }
  },
  // 展开 dept 数组(每个用户对应一个部门)
  {
    $unwind: "$dept"
  },
  // 按层级分组并统计用户数量
  {
    $group: {
      _id: "$dept.level",       // 按部门层级分组
      userCount: { $sum: 1 },   // 统计每个层级的用户数
      departmentNames: { $addToSet: "$dept.name" } // 收集部门名称
    }
  }
], { allowDiskUse: true });

3 department表$vlookup表user写法

cpp 复制代码
db.department.aggregate([
  // 步骤1:关联 user 表(类似 VLOOKUP)
  {
    $lookup: {
      from: "user",                   // 关联的集合名称(user 表)
      localField: "_id",              // department 表的关联字段(_id)
      foreignField: "department_id",  // user 表的关联字段(department_id)
      as: "users"                     // 将匹配的 user 文档存入 users 数组
    }
  },
  // 步骤2:计算每个 department 的用户数
  {
    $addFields: {
      user_count: { $size: "$users" } // 通过数组长度获取用户数
    }
  },
  // 步骤3:按 level 分组统计总用户数
  {
    $group: {
      _id: "$level",                  // 按 level 分组
      total_users: { $sum: "$user_count" } // 累加用户数
    }
  }
], { allowDiskUse: true });

user表vlookup表department写法 速度快于 department表vlookup表user写法

为什么呢?

user表$vlookup表department写法:

先读取user表数据

读取user表字段department_id值

根据department_id值去user表_id关联查找,user表的_id有索引,所以速度快

4 将user表的数据分别切割成10w、50w、100w、150w

cpp 复制代码
// 步骤 1:将符合条件的 50w 条数据写入新表
db.user.aggregate([
  { $match: { /* 筛选条件,如:age > 30 */ } }, // 可选:添加筛选条件
  { $limit: 1500000 },                            // 限制迁移数量
  { $out: "user150" }                           // 写入新表
], { allowDiskUse: true });                      // 允许磁盘临时存储

5 分别执行user表$vlookup表department写法sql,看看执行时间

user表10w 关联department表169w耗时10098ms

user表50w 关联department表169w耗时76067ms

user表100w 关联department表169w耗时174097ms

user表150w 关联department表169w耗时297307ms

假如读取一条user表耗时x,根据索引_id读取department耗时是y

100000x+100000y=10098

500000x+500000y=76067

1000000x+1000000y=174097

1500000x+1500000y=297307

处理1条数据大概需要0.1877ms

相关推荐
我系真滴菜31 分钟前
SQLiteStudio基本操作教程
数据库
q***498640 分钟前
在Django中安装、配置、使用CKEditor5,并将CKEditor5录入的文章展现出来,实现一个简单博客网站的功能
数据库·django·sqlite
q***18061 小时前
如何使用C#与SQL Server数据库进行交互
数据库·c#·交互
Wang's Blog1 小时前
MySQL: 操作系统对MySQL性能的影响及选型指南
数据库·mysql
Lucifer三思而后行1 小时前
Oracle ADG 配置闪回导致报表查询延时!
数据库·oracle
挨踢攻城1 小时前
【OCP考试喜报】2025.11月 ORACLE OCP 考试通过
数据库·mysql·oracle·dba·oracle ocp·公众号:厦门微思网络·ocp19c
纪莫1 小时前
技术面:MySQL篇(为啥会有非关系型数据库?MySQL的数据存储一定在磁盘吗?)
java·数据库·java面试⑧股
WangHappy1 小时前
Windows搭建MongoDB(5):Mongosh操作数据库常用命令总结
mongodb
ba_pi2 小时前
物联网中台搭建以及规则定义
物联网·mqtt·mongodb·tdengine·emqx·node-red
一 乐2 小时前
个人健康系统|健康管理|基于java+Android+微信小程序的个人健康系统设计与实现(源码+数据库+文档)
android·java·数据库·vue.js·spring boot·生活