mongodb大批量删除数据的方案对比
业务背景
系统中有个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大批量删除数据的方案对比相关推荐
- mongodb批量删除数据效率问题
今天接到一个任务,线上的mongodb积累了大量的无用数据,导致宕机,现在对里面的数据进行批量删除. 其中库里面的一个log记录有2000w+条,他的存储字段比较少,格式如下: { "_id ...
- mongodb 物理删除数据
刚开始用mongodb的时候,感觉很好用,速度很快,不过后面就遇到一个问题,数据物理内存一直增加,删除表也不管用. 然后网上找了各种办法,最后发现一个办法管用,就是物理删除存储数据. 操作如下: 1. ...
- mongodb定时删除数据(索引删除)
一 简介:本文介绍创建自动删除数据的TTL索引 二 目的 定时删除数据 三 创建方法 db.collection.createIndex(keys, options) options: ...
- 大数据量的MongoDB快速删除数据
一个Document,里面有2亿条数据.使用Java Driver. 原来的方法是 DBObject query = new BasicDBObject();query.put("value ...
- oracle批次处理数据_Oracle大批量删除数据方法(转)
批量删除海量数据通常都是很复杂及缓慢的,方法也很多,但是通常的概念是:分批删除,逐次提交. 下面是我的删除过程,我的数据表可以通过主键删除,测试过Delete和For all两种方法,for all在 ...
- SQL大批量删除数据
为了更好地阐述我所遇到的困难和问题,有必要做一些必要的测试和说明,同时这也是对如何解决问题的一种探究.因为毕竟这个问题的根本是如何来更好更快的操作数据,说到底就是DELETE.UPDATE.INSER ...
- MongoDB修改删除数据
将name是mongo的记录的name修改为mongo_new db.things.update({name:"mongo"},{$set:{name:"mongo_ne ...
- 删除数据oracle,oracle删除数据
oracle 动态删除,oracle监听之动态和静态注册,oracle删除数据,oracle删除用户 Oracle 删除数据的几种方法_计算机软件及应用_IT/计算机_专业资料.删除... oracl ...
- 深度对比Apache CarbonData、Hudi和Open Delta三大开源数据湖方案
摘要:今天我们就来解构数据湖的核心需求,同时深度对比Apache CarbonData.Hudi和Open Delta三大解决方案,帮助用户更好地针对自身场景来做数据湖方案选型. 背景 我们已经看到, ...
最新文章
- 状态模式(State)
- MSDN、RTM、OEM、VOL四大版本之区别
- SAP信用控制配置事物码
- 继BAT之后 第四大巨头是谁
- 语言三做一年级算题_一年级数学期末考试,学生交卷说能考100分,快让你家孩子试试吧...
- Mysql 启动失败没日志,MySQL Server 5.7将无法启动,并且未填充错误日志
- Java架构-JavaSE(一)之类与对象
- CSS3中的动画效果记录
- 深度解析艾瑞咨询《2017年度中国商业智能行业研究报告》
- 王秋杨的“前世”和她的“在路上”
- 获取context path或者basePath
- 老罗Android开发 视频教程
- 一部电影晓生活-韩国
- Git 拉取远程最新代码
- html炫酷文本框,炫酷的input框实现
- oracle 中符号%3e,Oracle 数据类型
- 群赛14----2017.9.24
- 利用mammoth.js将doc文档转为html
- Unity 3D游戏编程自学#7——NGUI入门
- Angular+arcgisjs之平面地图测距、测面积、搜索
热门文章
- Unity中的UGUI源码解析之事件系统(2)-EventSystem组件
- UV Toolkit贴图教程甜
- 使用Tableau制作帕累托图
- java面试中的各种排序
- 《Python》Python教程
- 第十一周作业——吃寿司
- 如何将Excel单元格内的信息通过回车换行拆分为多行或多列
- Go实战--golang中使用echo框架、MongoDB、JWT搭建REST API(labstack/echo、gopkg.in/mgo.v2、dgrijalva/jwt-go)
- 普通人想要创业成功的捷径是什么?
- 软件测试人员必备的32个网站清单,果断收藏了