• Mongo排序超32M问题解决 仅此而已


    背景

    事件列表分页查询时,报如下错:

    说明:事件表中,如果事件如果聚合了很多告警,那这些事件的大小就会很大

    问题分析

    问题说明

    MongoDB的 sort 操作是把数据拿到内存中再进行排序的,为了节约内存,默认给 sort 操作限制了最大内存为32M(mongo4.3以上版本是100M),当数据量超过限制后,就会抛异常。

    如果排序或者查询时,命中了排序字段,那排序的时候,只需要将排序字段拉到内存中进行排序,如果未命中索引,则会将查询出来的所有文档拉到内存中进行排序。

    代码分析

    先来看下报错那一行的代码:

    这里的排序,使用的是 lastDetectionTime 字段,来看下事件表建立的索引有哪些:

    通过代码可以看到,查询条件只有主键ID列表,所以排序的时候,是不会走任何索引的。

     

    解决方案

    方案一:修改排序限制(不推荐)

    将mongo排序限制改为100M。执行如下命令:

    /usr/local/qingteng/mongodb/bin/mongo --host localhost --port 27017 -u qingteng -p fMElKUz36MY00ceg --authenticationDatabase admin
    use amdin;
    db.runCommand({
        setParameter: 1,
        "internalQueryExecMaxBlockingSortBytes": 104857600
    });

    执行效果:

    方案二:排序字段创建索引(不推荐)

    由于现在的查询条件不会命中组合索引 comId_lastDetectionTime,那只需要改下这个索引就可以命中。

    删除组合索引comId_lastDetectionTime,新建组合索引lastDetectionTime_comId,命令:

    db.ids_incident.createIndex({lastDetectionTime:-1, comId:1},{name:"lastDetectionTime_comId"})

    方案三:修改查询条件

    既然现有的查询条件不会命中组合索引 comId_lastDetectionTime,那就改下查询条件,让查询字段带上该组合索引。修改后的代码如下:

    说明:最上面的IncidentQuery中是一定会包含comId、startTime、endTime的

  • 相关阅读:
    2019南昌网络赛-I(单调栈+线段树)
    poj3250(单调栈模板题)
    poj2528(线段树+离散化)
    poj2828(线段树查找序列第k小的值)
    Seikimatsu Occult Tonneru(网络流,状态数(建不建边)不多时,可考虑直接进行枚举
    A. Coffee Break(思维题,类似于邻接表的head数组用法)
    E. Paint the Tree(树形dp)
    cdq分治学习
    2018SEERC Points and Rectangles (CDQ分治)
    SEERC 2018 Inversion
  • 原文地址:https://www.cnblogs.com/xuwenjin/p/16393900.html
Copyright © 2020-2023  润新知