当前位置: 首页 > news >正文

mongodb聚合排序的一个巨坑

现象:

mongodb cpu动不动要100%,如下图

b33bd5ddcbe55a25de93863f6f415f1d.png               

分析原因:

查看慢日志发现,很多条这样的查询,一直未执行行完成,占用大量的CPU

[{$match: {"tags.taskId": "64dae0a9deb52d2f9a1bd71e",grnty: "minute","tags.type": "task","tags.taskRecordId":"64e5c004133738231bc36906",},},{$sort: {_id: -1,},},{$limit: 5,},{$unwind: "$ss",},{$group: {_id: "$ss.vs.inputQps",qps: {$avg: "$ss.vs.inputQps",},},},
]

查看程序里面有一段聚合的代码

Criteria criteria = new Criteria();
tags.forEach((k,v)->{String format = String.format(TAG_FORMAT, k);criteria.and(format).is(v);
});
criteria.and(MeasurementEntity.FIELD_GRANULARITY).is(Granularity.GRANULARITY_MINUTE);
MatchOperation match = Aggregation.match(criteria);
SortOperation sort = Aggregation.sort(Sort.by(Sort.Direction.DESC, "_id"));
LimitOperation limit = Aggregation.limit(5);
UnwindOperation unwind = Aggregation.unwind("ss", false);
GroupOperation group = Aggregation.group().avg("ss.vs.inputQps").as("qps");
Aggregation aggregation = Aggregation.newAggregation(match, sort, limit, unwind, group);

看一下这个代码也没有多大问题,但是就是执行很慢很慢,于是我explain这条语句,发现是先执行全集合sort 然后再match的,理论上应该是先match,然后再执行针对查询的结果做sort的

afc8284f9012b97ba7173a34d6b04b0b.png

已经使用了 $match 和 $sort 操作来筛选和排序文档。仍然对整个集合进行了排序?

这可能是由于 MongoDB 的查询优化器在执行查询时做出的决策。在 MongoDB 中,查询优化器会尝试根据查询计划和索引来优化查询性能。在某些情况下,优化器可能会选择在 $match 操作之后对整个集合进行排序,而不仅仅是对 $match 操作筛选出的文档进行排序。这可能是因为优化器认为在整个集合上进行排序的成本更低,或者由于其他优化策略。如果你希望只对 $match 操作筛选出的文档进行排序,可以尝试使用索引来优化查询。确保你的查询条件和排序字段都有适当的索引,这样可以帮助优化器做出更好的决策,以便只对筛选结果进行排序。

解决方案

在这种情况下,你可以尝试创建一个复合索引,包含筛选条件和排序字段。例如,你可以创建一个包含 "tags.taskId","grnty","tags.typ","tags.taskRecordId","_id" 字段的复合索引。这样,MongoDB 在执行查询时可以使用该索引来加速筛选和排序操作。

 总结

为了只对筛选结果进行排序,你可以尝试以下步骤:

  1. 创建一个复合索引,包含筛选条件和排序字段。

  2. 确保查询条件和排序字段在索引中的顺序与聚合管道中的顺序一致。

  3. 使用 explain() 方法来查看查询的执行计划和索引使用情况,以便进行优化。

http://www.lryc.cn/news/147312.html

相关文章:

  • 无涯教程-分类算法 - 随机森林
  • c#常见的排序算法
  • Redis 持久化和发布订阅
  • k8s使用ECK(2.4)形式部署elasticsearch+kibana-http协议
  • [maven]关于pom文件中的<relativePath>标签
  • 11. 网络模型保存与读取
  • 新SDK平台下载开源全志V853的SDK
  • 多图详解VSCode搭建Java开发环境
  • 基于JavaWeb和mysql实现网上书城前后端管理系统(源码+数据库+开题报告+论文+答辩技巧+项目功能文档说明+项目运行指导)
  • Swift创建单例
  • 问道管理:市盈率怎么计算?
  • Ansible File模块,Ansible File模块详解,文件管理的自动化利器
  • 记录http与mqtt的区别
  • 导入excel数据给前端Echarts实现中国地图-类似热力图可视化
  • 【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询
  • 微信小程序使用本地图片在真机预览不显示的问题解决
  • Texlive2023与Texstudio2023卸载与安装(详细全程)
  • 塞浦路斯公司注册 塞浦路斯公司开户 塞浦路斯公司年审
  • XSS盲打练习(简单认识反射型、存储型XSS和cookie欺骗)
  • Shell脚本:基础知识和使用指南
  • Resource Hacker下载
  • Kubernetes入门 十、HPA 自动扩/缩容
  • Django报错:SystemCheckError: System check identified some issues解决办法
  • JavaScript设计模式(一)——构造器模式、原型模式、类模式
  • python 读文件,跳过有问题的那行
  • Spring Boot Actuator的Env端点存在本地文件包含(LFI)漏洞CVE-2020-5421
  • Leetcode 最后一个单词的长度
  • css ,less和sass的区别[简洁易懂
  • 有了ChatGPT的帮助,开发者的生产力会提高10-100倍
  • win10+QT5.15+cryptopp562 完整配置开发