业务背景

系统中有个mongodb集合每天增长上千万,时间长了,系统中这个集合已经有几亿数据了,需要写一个定时任务,把集合中三个月前的数据删除,并且后面每天凌晨执行这个定时任务.

方案分析

方案一

使用Mongo的游标MongoCursor,遍历获取集合id获取id列表idList,然后根据idList批量删除

方案二

使用mongoTemplate.find,每次查询1万条数据,遍历获取集合id获取id列表idList,然后根据idList批量删除

代码片段

方案一

    /*** 删除集合数据** @param time 传三个月前的时间戳*/private void deleteData(Long time) {Query query = new Query(new Criteria("ct").lt(time));MongoCursor<Document> dbCursor = mongoTemplate.getCollection(COLLECTION_NAME).find(query.getQueryObject())//设置游标查询不超时.noCursorTimeout(true)//设置批量从数据库中获取的数据量.batchSize(10000).iterator();int i = 0;List<String> idList = new ArrayList<>();Document next;while (dbCursor.hasNext()) {i++;next = dbCursor.next();String id = next.get("_id").toString();idList.add(id);if (i % 10000 == 0) {List<String> idListToDelete = new ArrayList<>();idListToDelete.addAll(idList);// 清空数据idList.clear();log.info("delete: {}", i);// 异步删除数据threadPool.execute(new Runnable() {@Overridepublic void run() {doDeleteData(idListToDelete);}});}}// 再次判断if (CollectionUtils.isNotEmpty(idList)) {doDeleteData(idList);idList.clear();}log.info("data delete total: {}", i);}

方案二

    /*** 删除集合数据** @param time 传3个月前时间戳*/private void deleteData(Long time) {Query query = new Query(new Criteria("ct").lt(time));// 只需要去_id字段即可,避免取多个字段,数据量大了占内存过多query.fields().include("_id");query.limit(10000);List<XXX> xxxList = mongoTemplate.find(query, XXX.class);List<String> idListToDelete;int i = 0;while (CollectionUtils.isNotEmpty(xxxList)) {i += xxxList.size();idListToDelete = xxxList.stream().map(o -> o.getId()).collect(Collectors.toList());doDeleteData(idListToDelete);log.info("delete: {}", i);xxxList = mongoTemplate.find(query, XXX.class);}log.info("delete total: {}", i);}
    /*** 执行删除数据*/private void doDeleteData(List<String> idList) {long s0 = System.currentTimeMillis();Query query = new Query(new Criteria("_id").in(idList));mongoTemplate.remove(query, XXX.class);long s1 = System.currentTimeMillis();log.info("delete data size: {}, cost: {}", idList.size(), (s1 - s0));}

对比

两种方案都是可行的,只不过是速度上的差别,大致速度如下(当时没有记录数据,大致是这个速度)

发送量 方案一(游标) 方案二(query)
10万 7s 4s
400万 7分 2分

总结

实际在测试的过程中,发现删除数据其实花费时间很少,大概200多毫秒删1万条,但MongoCursor在遍历循环的时候比较耗时while (dbCursor.hasNext()) { }。

而mongoTemplate.find在查询的数据的时候,如果数据有索引,每次查询1万条其实速度是挺快的,根据找到符合条件的1万条数据,立即返回。(顺便说下,mongoTemplate.count计算总数比较慢)

遇到类似的问题,可以结合业务,对两种方案进行测试,一般第二种方案效率更高一点。

有其他更好的方案欢迎交流!

mongodb大批量删除数据的方案对比相关推荐

  1. mongodb批量删除数据效率问题

    今天接到一个任务,线上的mongodb积累了大量的无用数据,导致宕机,现在对里面的数据进行批量删除. 其中库里面的一个log记录有2000w+条,他的存储字段比较少,格式如下: { "_id ...

  2. mongodb 物理删除数据

    刚开始用mongodb的时候,感觉很好用,速度很快,不过后面就遇到一个问题,数据物理内存一直增加,删除表也不管用. 然后网上找了各种办法,最后发现一个办法管用,就是物理删除存储数据. 操作如下: 1. ...

  3. mongodb定时删除数据(索引删除)

    一 简介:本文介绍创建自动删除数据的TTL索引 二 目的 定时删除数据 三 创建方法    db.collection.createIndex(keys, options)    options:   ...

  4. 大数据量的MongoDB快速删除数据

    一个Document,里面有2亿条数据.使用Java Driver. 原来的方法是 DBObject query = new BasicDBObject();query.put("value ...

  5. oracle批次处理数据_Oracle大批量删除数据方法(转)

    批量删除海量数据通常都是很复杂及缓慢的,方法也很多,但是通常的概念是:分批删除,逐次提交. 下面是我的删除过程,我的数据表可以通过主键删除,测试过Delete和For all两种方法,for all在 ...

  6. SQL大批量删除数据

    为了更好地阐述我所遇到的困难和问题,有必要做一些必要的测试和说明,同时这也是对如何解决问题的一种探究.因为毕竟这个问题的根本是如何来更好更快的操作数据,说到底就是DELETE.UPDATE.INSER ...

  7. MongoDB修改删除数据

    将name是mongo的记录的name修改为mongo_new db.things.update({name:"mongo"},{$set:{name:"mongo_ne ...

  8. 删除数据oracle,oracle删除数据

    oracle 动态删除,oracle监听之动态和静态注册,oracle删除数据,oracle删除用户 Oracle 删除数据的几种方法_计算机软件及应用_IT/计算机_专业资料.删除... oracl ...

  9. 深度对比Apache CarbonData、Hudi和Open Delta三大开源数据湖方案

    摘要:今天我们就来解构数据湖的核心需求,同时深度对比Apache CarbonData.Hudi和Open Delta三大解决方案,帮助用户更好地针对自身场景来做数据湖方案选型. 背景 我们已经看到, ...

最新文章

  1. 状态模式(State)
  2. MSDN、RTM、OEM、VOL四大版本之区别
  3. SAP信用控制配置事物码
  4. 继BAT之后 第四大巨头是谁
  5. 语言三做一年级算题_一年级数学期末考试,学生交卷说能考100分,快让你家孩子试试吧...
  6. Mysql 启动失败没日志,MySQL Server 5.7将无法启动,并且未填充错误日志
  7. Java架构-JavaSE(一)之类与对象
  8. CSS3中的动画效果记录
  9. 深度解析艾瑞咨询《2017年度中国商业智能行业研究报告》
  10. 王秋杨的“前世”和她的“在路上”
  11. 获取context path或者basePath
  12. 老罗Android开发 视频教程
  13. 一部电影晓生活-韩国
  14. Git 拉取远程最新代码
  15. html炫酷文本框,炫酷的input框实现
  16. oracle 中符号%3e,Oracle 数据类型
  17. 群赛14----2017.9.24
  18. 利用mammoth.js将doc文档转为html
  19. Unity 3D游戏编程自学#7——NGUI入门
  20. Angular+arcgisjs之平面地图测距、测面积、搜索

热门文章

  1. Unity中的UGUI源码解析之事件系统(2)-EventSystem组件
  2. UV Toolkit贴图教程甜
  3. 使用Tableau制作帕累托图
  4. java面试中的各种排序
  5. 《Python》Python教程
  6. 第十一周作业——吃寿司
  7. 如何将Excel单元格内的信息通过回车换行拆分为多行或多列
  8. Go实战--golang中使用echo框架、MongoDB、JWT搭建REST API(labstack/echo、gopkg.in/mgo.v2、dgrijalva/jwt-go)
  9. 普通人想要创业成功的捷径是什么?
  10. 软件测试人员必备的32个网站清单,果断收藏了