【后端面试题】【中间件】【NoSQL】MongoDB查询优化2(优化排序、mongos优化)

优化排序

在MongoDB里面,如果能够利用索引来排序的话,直接按照索引顺序加载数据就可以了。如果不能利用索引来排序的话,就必须在加载了数据之后,再次进行排序,也就是进行内存排序。

可想而知,如果内存排序,再叠加分页查询的话,性能会更差。比如你要查询skip(10000).limit(100),那么在最坏情况下,MongoDB要把所有的文件加载到内存里排序,然后找到从10000开始的100条数据

优化的思路也类似MySQL。第一种是把查询优化成利用索引来排序,可以考虑修改查询,也可以考虑修改索引。比如你可以新建索引。

我还优化过一个分页查询。早期的时候,有一个查询是需要排序加分页的,但是最开始数据量不多,所以随便写了也没问题。但是后面数据量上来以后,这个地方查询就越来越慢。看到这个排序加分页的查询,我第一个想法就是这个查询肯定是内存查询,不然不会这么慢。一排查果然是这样,后来创建了一个新的索引,确保排序的时候可以直接利用索引来排序。

另一种优化思路是借鉴在分库分表里提到的禁止跨页查询,也就是每次查询带上上一次查询的极值作为查询条件。

MongoDB的分页查询还有一种优化方式,但是这种优化方式需要业务折中。也就是原来分页向后翻页是通过偏移量来进行的,那么现在可以通过修改查询条件,在查询语句里带上前一页的排序字段的极值。比如我们的查询是根据创建时间create_time倒序排序,那么就可以优化成查询条件里上一批最小的create_time,接近于WHERE create_time <= $last_min_create_time的语义

注意,这里的极值是最大值还是最小值,跟你的排序有关。

另外你可以进一步把话题引导到MySQL和分库分表上。

总体来说,MongoDB的分页查询面临的问题和关系型数据库分页查询面临的问题差不多,而在分片集合上进行分页查询的问题,也和分库分表的问题差不多。总之,分页查询如果不小心的话,是比较容易出现性能问题的。

既然MongoDB会有这种分页的问题,那么分片情况下处理分页的mongos岂不是容易成为瓶颈吗?

所以就可以考虑增加mongos的数量

增加mongos数量

如果是分片集合的话,查询都要靠mongos来执行路由,并且合并结果集

换一句话来说,mongos就是查询的性能瓶颈,它可能是CPU瓶颈、内存瓶颈或网络带宽瓶颈。比如,你有分片查询,那么mongos就必须要求各个分片查询到结果之后,自己再排序,选出全局分页里对应的数据

因此,在实践中要密切关注查询性能,并且发现查询很慢的时候,就要去看看是不是mongos引起的。

之前我还优化过mongos,不过mongos实例能优化的不多,主要就是增加mongos实例,而且最好是能独立部署mongos,独享系统的CPU和内存资源。

另一种面试的思路是隔离 ,也就是要考虑到mongos本身容易称为性能瓶颈,并且你也不能无限增加mongos实例,所以如果公司资源足够,应该让核心业务使用独立的mongos实例,或者说独立的MongoDB集群

并且,为了保证核心服务的查询效率和稳定性,我都是单独准备了一个集群给核心服务,这样可以保证核心服务的mongos互相之间没影响

相关推荐
葫芦和十三3 小时前
图解 MongoDB 30|查询路由与广播查询:带片键定向,不带就广播
后端·mongodb·agent
葫芦和十三3 小时前
图解 MongoDB 29|分片键陷阱:jumbo chunk、孤儿文档和写入热点
后端·mongodb·agent
进击的程序猿~3 小时前
Go Zero源码阅读1
后端·golang
阿成学长_Cain4 小时前
Linux ipcs 命令超全详解:查看共享内存 / 消息队列 / 信号量,IPC 运维必备
linux·运维·服务器·网络·数据库
2601_961593425 小时前
Rust 开发环境配置繁琐?RustRover 开箱即用搞定编码调试
开发语言·后端·macos·rust
OceanBase数据库官方博客6 小时前
OceanBase AI 时代,数据库的变与不变(技术解析与实践)
数据库·人工智能·oceanbase
犀利豆7 小时前
AI in Harness(三)
人工智能·后端
阿成学长_Cain7 小时前
Linux dirs命令详解|Bash目录堆栈管理快速切换目录实战教程
linux·运维·前端·数据库
ywl4708120877 小时前
Mysql 平衡二叉树、红黑树、B树、B+树区别以及应用场景(五)
数据库·b树·mysql
IT_陈寒8 小时前
Java的Stream.parallel()把我CPU跑爆了,这种优化要谨慎
前端·人工智能·后端