【后端面试题】【中间件】【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互相之间没影响

相关推荐
独行soc16 分钟前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
White_Mountain34 分钟前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu
Code apprenticeship35 分钟前
怎么利用Redis实现延时队列?
数据库·redis·缓存
百度智能云技术站38 分钟前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle
装不满的克莱因瓶40 分钟前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
404NooFound1 小时前
Python轻量级NoSQL数据库TinyDB
开发语言·python·nosql
GISer_Jing2 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试
m0_748245522 小时前
吉利前端、AI面试
前端·面试·职场和发展
梦想平凡2 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
isolusion2 小时前
Springboot的创建方式
java·spring boot·后端