【MongoDB】--MongoDB的Sort排序问题

目录

一、问题背景描述

1.1、问题背景

现实系统页面翻页到20000页之后,出现异常报错。

caused by :: Sort operation used more than the maximum 67108864 bytes of RAM.

经过排查分析,Sort操作超过了MongoDB单个Session排序可使用的最大内存限制。这里针对Sort排序支持的最大内存限制是64M。

1.2、问题分析

经过排查,sort排序的字段未使用到索引,sort时触发内存限制而报错。对此,我们解决问题思路如下:

(1).调整sort排序时内存限制;

(2).给要查询的字段创建合适的索引;

(3).对于复杂多变的查询场景,无法创建所有的索引,有什么其他办法解决?

二、建立索引支持深度翻页查询

2.1、调整sort排序的内存限制【不建议】

java 复制代码
# 比如调大到 128M
## 在线调整
> db.adminCommand({setParameter:1, internalQueryExecMaxBlockingSortBytes:134217728})

## 持久到配置文件
setParameter:
internalQueryExecMaxBlockingSortBytes: 134217728

2.2、创建索引

如果查询语句的排序是单列排序,那么直接加索引即可,(升序/降序)排序规则无影响。

如果查询的排序是使用组合排序,那么需要建立合适的索引。

//-1:表示降序 1:表示升序

@CompoundIndex(name = "un_index_a_b", def = "{a:1,b:-1}", unique = true)

@CompoundIndex(name = "un_index_a_b", def = "{a:1,b:1}")

上面是我们常见创建的组合索引,设定字段升序或降序。可以使用explain()方法来判断是否使用了索引。这样针对具体问题,创建合适的索引,能够解决一些问题。

创建索引的语句如下:

java 复制代码
db.wwy_table.dropIndex("a_1_b_-1");
db.wwy_table.createIndex(
    {
        a: 1,
        b: -1
    },
    {
        name: "un_index_a_b"
    }
);

------经过测试,建立合适的索引并且语句执行使用了索引,查询没问题。

2.3、拓展--组合索引什么时候失效

java 复制代码
现有wwy_table表,有索引@CompoundIndex(name = "un_index_a_b", def = "{a:1,b:-1}")。
db.wwy_table.find({
        delete: false
    })
    .sort({
        a: 1,
        b: 1
    }).explain('executionStats')

如下几种方式失效或生效



-----从上面可以看出,sort的升序/降序和创建的索引顺序全部相同或全部相反,才会走索引。


二、聚合查询解决深度翻页查询

对于shell的find()查询方法,深度查询往往会触发sort的内存限制,对此,我们可以使用聚合查询aggregate()方法。aggregate()方法使用内存排序能用最大的内存时100M。如果在使用中,避免报错,可以需要添加?{allowDiskUse : true}?参数。

java 复制代码
        Criteria criteria = new Criteria();
        criteria.and("sid").is(521131);

        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria), //主mongodb自身查询条件
                Aggregation.sort(new Sort(Sort.Direction.DESC, "update_time")),
                Aggregation.skip((page-1)*size),
                Aggregation.limit(size)
        ).withOptions(AggregationOptions.builder().allowDiskUse(true).build()); //解决内存不够问题

MongoDB将在聚合操作期间使用磁盘来存储数据,以便在结果集较大时能够正常完成操作。这对于处理大型数据集非常有用。

相关推荐
csdn杰哥14 小时前
瑞萨单片机开发教程[二十七] DTC 外部中断触发传输实验
单片机·嵌入式硬件·mongodb·瑞萨·ra6m5
csdn杰哥17 小时前
瑞萨单片机开发教程[二十六] DMAC 存储器数据传输实验
单片机·嵌入式硬件·mongodb·瑞萨·ra6m5
铅笔小新z18 小时前
【stm32】GPIO
stm32·嵌入式硬件·mongodb
西门啐血1 天前
上位机开发之假装有设备,使用 C# 模拟串口设备
开发语言·mongodb·c#
吴声子夜歌2 天前
MongoDB 8.0——聚合
数据库·mongodb
吴声子夜歌3 天前
MongoDB 8.0——可视化管理工具
数据库·mongodb
吴声子夜歌3 天前
MongoDB 4.2——安装 MongoDB
数据库·mongodb
吴声子夜歌3 天前
MongoDB 8.0——MongoDB的安装
数据库·mongodb
吴声子夜歌4 天前
MongoDB 4.2——了解应用程序的动态
数据库·mongodb
czhaii4 天前
STC ai助手单片机工程项目创建实例
数据库·mongodb