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

相关推荐
松涛和鸣1 小时前
72、IMX6ULL驱动实战:设备树(DTS/DTB)+ GPIO子系统+Platform总线
linux·服务器·arm开发·数据库·单片机
likangbinlxa1 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
r i c k2 小时前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦2 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL3 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·3 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德3 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫3 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i3 小时前
完全卸载MariaDB
数据库·mariadb
纤纡.4 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql