千家信息网

关于MongoDB aggregate的性能优化经历分享

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,今天小编给大家分享的是关于MongoDB aggregate的性能优化经历,一起来看看吧。在一台配置为2核4G的阿里云服务器上,硬盘是普通的云盘(即SATA盘),除mongoDB外,运行了若干个jav
千家信息网最后更新 2025年02月01日关于MongoDB aggregate的性能优化经历分享

今天小编给大家分享的是关于MongoDB aggregate的性能优化经历,一起来看看吧。

在一台配置为2核4G的阿里云服务器上,硬盘是普通的云盘(即SATA盘),除mongoDB外,运行了若干个java应用,单节点mysql和redis,mongo的实际可用内存在1.5G左右。单表数据200万条的时候,一个聚合函数响应时间约为6秒,页面端每秒请求一次,由于响应不够及时,页面刷新不及时,服务端堆积了大量的mongo aggregate请求,系统可用内存不足,直接导致了溢出,mongo服务被动shutdown。


mongod(ZN5mongo15printStackTraceERSo+0x41) [0x55bd3a2dd321]
mongod(ZN5mongo29reportOutOfMemoryErrorAndExitEv+0x84) [0x55bd3a2dc954]
mongod(ZN5mongo12mongoReallocEPvm+0x21) [0x55bd3a2d22b1]
mongod(ZN5mongo11BufBuilderINS21SharedBufferAllocatorEE15growreallocateEi+0x83) [0x55bd38981833]
mongod(ZN5mongo3rpc17OpMsgReplyBuilder22getInPlaceReplyBuilderEm+0x80) [0x55bd39d4b740]
mongod(+0xAB9609) [0x55bd389be609]
mongod(+0xABBA59) [0x55bd389c0a59]


下面是聚合的脚本,很简单,就是统计某辆车多个状态码的最新值(通过$first实现)。

db.getCollection("vinMsgOut").aggregate([  {"$match": {"vinCode": "LSGKR53L3HA149563"}},  {"$sort": {"postTime" : -1}},  {"$group":  {      "_id": "$messageType",      "resultValue": {"$first": "$resultValue"}      }  }],{ allowDiskUse: true })

第一反应是增加过滤条件及增加索引。
结合业务,增加时间条件过滤,将$match改为:

{"$match": {"vinCode": "LSGKR53L3HA149563", "createTime": {$gt: ISODate("2020-03-01T06:30:12.038Z")}}}

再分别为vinCode和createTime创建索引,执行,依旧是6秒多。。。
将$sort的字段改成索引字段createTime,
{"$sort": {"createTime" : -1}}
再次执行,时间依旧是6秒多。。。

由于系统可分配内存有限,存储引擎已经默认是最快的wiredTiger,磁盘也没法更给力,只能从业务上再着手。考虑到这些最新状态的出现,一般都是同一个时间段,状态码只有几百个,如果sort之后,只从pipe取其中一部分进行group,会不会更快些?带着这个疑问,我加了一条limit。

db.getCollection("vinMsgOut").aggregate([  {"$match": {"vinCode": "LSGKR53L3HA149563", "createTime": {$gt: ISODate("2020-03-01T06:30:12.038Z")}}},  {"$sort": {"createTime" : -1}},  {"$limit": 1000},  {"$group":  {      "_id": "$messageType",      "resultValue": {"$first": "$resultValue"}      }  }],{ allowDiskUse: true })

结果是秒回!

去掉$match中的createTime条件,依旧秒回!这是否意味着createTime索引并没有起作用?带着疑问,将createTime索引删掉,返现时间变成5秒,所以createTime的索引是有用的,用在$sort而已。综上,完成了整个查询的优化,总结下来就是:

  1. $match条件需要增加索引,如果是多个,最好用组合索引;
  2. $sort的字段也需要增加索引;
  3. $group的_id也需要增加索引;
  4. limit可以大幅度降低时耗。
  5. 关于MongoDB aggregate的性能优化经历分享到这里了,当然并不止以上和大家分析的办法,不过小编可以保证其准确性是绝对没问题的。希望以上内容可以对大家有一定的参考价值,可以学以致用。如果喜欢本篇文章,不妨把它分享出去让更多的人看到。
索引 时间 条件 内存 字段 状态 服务 性能 业务 多个 就是 疑问 系统 页面 最快 学以致用 万条 不够 价值 作用 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全实用技术第三版 数据库连接12543 慈溪计算机软件开发项目 大数据是软件开发吗 长沙商学院有软件开发吗 司单位如何网络安全备案 ARCMAP连接PG数据库 一个库存系统数据库表如何设计 中国网络安全最强的公司 护士从前软件开发公司的人员 汤森路透医药数据库 黑龙江共青团网络安全直播 广州智能建模软件开发 平谷区综合网络技术服务大概费用 网络安全从我做起手抄报视频 steam觉得你无权加入服务器 上海通用软件开发报价表 数据库运行 软件开发文档ppt 网络安全工作先进个人推荐材料 toad怎么远程数据库 如何备份msde数据库 钉钉如何建立数据库 机关网络安全视频 服务器有基础防护功能吗 笔记本设置为服务器系统要改吗 河北交友软件开发哪家好 微致互联网科技有限公司官网 涉密网络安全风险评估制度 计算机网络技术可以当黑客吗
0