22.MongoDB删除操作效率及相关问题验证

news2024/11/16 0:05:28

最近遇到一个了一个MongoDB数据删除的问题,需要一次性删除上线即1.5年前~1年前的数据且之后每天清空一年过期的数据。在数据量比较大的情况下何种方式的删除效率最高是一个值得研究的问题,本文通过实际测试找出其中规律。

本文采用腾讯云mongodb集群进行验证。mongd配置较弱为2核4G,验证仅仅针对副本集不涉及分片集群。测试数据集如下,共计1000w条数据。接下来会以systime字段作为筛选条件验证影响删除操作耗时的因素都有哪些。

kfuin_beg = 0
kfuin_end = 1
for(var num = kfuin_beg; num < kfuin_end; num++){
    var kfuin_num = num+1;//主号数
    var cid_num = 10000 //1万个cid
    var session_num = 10//每个cid有10通会话
    var detail_num = 99//每个session有9条消息
    var docs = [];
    for(var i = num; i < kfuin_num; i++){
        for(var j = 0; j < cid_num; j++){
            for(var k = 0; k < session_num; k++){ 
                var kfuin_val = i + 2852000000
                var session_index_name_val = "event_session_" + kfuin_val.toString() + "_wx58b4690f0ab8193f-" + j.toString()
                var session_id_val = "session_id" + "_wx58b4690f0ab8193f-" + j.toString() + "_" +(k).toString()
                var systime_val = 1600000000000000 + j*10000 + k*1000
                docs.push({kfuin:kfuin_val,key:session_index_name_val,session_id:session_id_val,systime:systime_val})
                for(var h = 0; h < detail_num; h++){ 
                    var detail_index_val = "event_detail_" + kfuin_val.toString() + "_wx58b4690f0ab8193f-" + j.toString()
                    systime_val = 1600000000000000 + j*10000 + k*1000 + h
                    docs.push({kfuin:kfuin_val,key:detail_index_val,session_id:session_id_val,systime:systime_val})
                }
            }
            print("complete cid!!")
        }
    }
    print("insert docs!!")
    db.coll.save(docs)
}

零、MongoDB删除数据不释放空间??

MongoDB 3.6版本之后默认使用的存储引擎是WiredTiger。

①这个引擎有个特点,那就是remove删除数据不释放空间。举个例子:你现在的集合里面有1亿条数据,占用10G空间;即便你删除了其中的99999999条数据都删了,其占用的空间仍然是10GB。

②如果想彻底释放空间,最直接的方法就是删除整个集合(db.coll_0.drop())或者删除整个数据库(dropDatabases())。

③虽然磁盘利用率下不来但是对于新查询的数据只要总数据大小不超过10GB前,MongoDB都不会申请额外的硬盘空间。注:上面会有一些碎片无法完全回收,即对于“每天定时删除180d前数据这个场景”磁盘利用率还是会增长的,只不过速度会慢很多。

④如果你的MongoDB允许暂停读写操作,可以在Mongo Shell中使用compact命令释放空间。命令格式如下。

db.runCommand({'compact': '集合名'})

在MongoDB 4.4之前的版本,compact会阻塞整个库的增删改查操作,所以需要业务允许暂停全部读写才能执行;在4.4版本之后,compact命令几乎可以在除了删除集合、增删索引外的任何时候执行。

注:这是一个高危的操作,一定要充分验证/慎重。。。。。



https://www.mongodb.com/docs/manual/reference/command/compact/#dbcmd.compact

一、remove和deleteMany的区别

直接抛结论:就耗时方面似乎没有什么区别!!!

二、remove操作的耗时验证

1、无systime字段索引的删除测试

(0)访问某条具体的数据

db.coll.find({systime:1600000000022002}) 

耗时5s

(1)删除某条具体的数据

db.coll.remove({systime:1600000000022002})

耗时5s

结论:显然这个耗时是定位这条目标数据的耗时。

(2)删除其中的50W条数据

db.coll.find({systime:{"$lte":1600000005000000}}).count()
db.coll.remove({systime:{"$lte":1600000005000000}})  
#耗时19s  注:大概就是遍历用5秒+加上删除50w数据需要了14s。

结论:这个耗时应该是遍历数据用了5秒,删除50w数据用了14s。

(3)删除其中的450w条数据

db.coll.find({systime:{"$lte":1600000050000000}}).count()  
db.coll.remove({systime:{"$lte":1600000050000000}})   
#耗时190s  注:主要还是删除数据的耗时

2、有systime字段索引的删除测试

准备:创建systime字段的索引

db.coll.createIndex({systime:1})

(0)访问某条具体的数据

db.coll.find({systime:1600000000022002}) 
#瞬间 耗时1ms

(1)删除某条具体的数据

db.coll.remove({systime:1600000000022002})
#瞬间  耗时1ms

结论: 很容易理解。有索引所以瞬间定位到删除目标消息,删除的仅仅是一条所以删除操作也很快。

(2)删除其中的50W条数据

db.coll.find({systime:{"$lte":1600000005000000}}).count()
db.coll.remove({systime:{"$lte":1600000005000000}})  
#耗时15s  注:应该大部分时间都是删除消耗的;

(3)删除其中的450w条数据

db.coll.find({systime:{"$lte":1600000050000000}}).count() 
db.coll.remove({systime:{"$lte":1600000050000000}})   
#185秒  注:systime索引带来的负担还好诶;但是也确实意义不大。

结论:如果只是一个systime字段的索引给删除带来的负担感觉还好。

3、更多索引对删除效率的影响

准备:累计创建如下四个索引

db.coll.createIndex({systime:1})
db.coll.createIndex({kfuin:1})
db.coll.createIndex({key:1})
db.coll.createIndex({key:1,systime:1})

(1)删除其中的50w条数据

db.coll.find({systime:{"$lte":1600000005000000}}).count()
db.coll.remove({systime:{"$lte":1600000005000000}})  
#耗时22s  注:过多的索引确实会对删除效率产生负面影响,这个额外的三个索引是耗时变为原来的1.5倍左右。

(2)删除其中的450w条数据

db.coll.find({systime:{"$lte":1600000050000000}}).count() 
db.coll.remove({systime:{"$lte":1600000050000000}})   
#250秒 注:过多的索引确实会对删除效率产生负面影响,这个额外的三个索引是耗时变为原来的1.5倍左右。

结论:过多的索引确实会对删除效率造成影响;对于测试中额外多增加了三个索引删除耗时约为没有这三个索引的1.3~1.5倍左右。

4、删除操作的集群资源消耗情况

这个操作看起来主要消耗的是cpu,对于测试集群目标分片的cpu消耗在90%+。

3、结论

1、remove和deleteMany在效率上没有什么区别,以后统一用remove好了。

2、拆开来讲删除操作需要的耗时主要包括两块:①遍历到目标数据的耗时 ②删除消息的耗时。对于前者 如果删除一条数据的话就理解为定位到目标数据;如果有索引的情况下就理解为定位到需要删除数据的起始删除目标位置点。

注:oa环境低配机器无索引情况下删除100w条数据大概需要30s。
注:oa环境低配机器无索引情况下遍历100w数据需要0.5s(1000w数据5s)。

3、建立筛选字段的索引确实会对寻找删除数据、删除数据位置点都有帮助;但同时索引也会给删除操作带来负担。

4、究竟什么删除策略好还是要结合你的数据集和想要删除的数据集。

case1:数据集很大一次性删除很少的数据 —— 显然需要建立索引。

case2:数据集很大删除的数据也很多 —— 此时定位删除位置点的耗时就显得不那么重要了,主要耗时都在删除操作本身上了;极端情况下如果我们要删除目标数据集中的80%以上的数据这个时候建不建索引影响不大。

5、现在结论也比较清晰了。

(1)第一波删除的时候大概要清理其中的三分之一的数据,这个时候有systime索引更好没有感觉问题也不大(遍历的耗时和删除的耗时速度起码差了60倍)。

(2)后续如果你需要systime维度的每天删除一波过期数据应该还是要systime更好。

(3)这个时候关注重点应该是测试目标集群对一个索引后台创建索引、删除数据的资源消耗的情况,如果没问题就可以实施了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于java的连连看游戏设计-计算机毕业设计

项目介绍 基于java设计的连连看游戏规则是模仿网络上的最普通的连连看游戏&#xff0c;主要是鼠标点击两次的图片能否消去的问题。当前&#xff0c;前提是点击两张相同的图片&#xff0c;若是点击的是同一张图片或者两张不同的图片&#xff0c;则不予处理。在两张相同的图片所…

这份pdf成功让我拿下了蚂蚁金服、字节跳动、小米等大厂的offer

关于程序员&#xff0c;除了做项目来提高自身的技术之外&#xff0c;还有一种提升自己的专业技能就是&#xff1a;多&#xff01;看&#xff01;书&#xff01; 小编整理出一篇Java进阶架构师之路的核心知识&#xff0c;同时也是面试时面试官必问的知识点&#xff0c;篇章也是…

点云可视化工具

点云可视化工具 平时查看点云文件主要是用CloudCompare&#xff0c;基本上也就是打开看看这个点云大概是个什么样子&#xff0c;很少会在CloudCompare对点云进行处理&#xff0c;它可以直接将点云拖进软件进行显示也还是挺方便的。但是还是有点点不是很方便的地方&#xff0c;…

Linux从入门到进阶学习(Ⅲ):Linux权限管控

目录 1 root用户 1.1 su 1.2 sudo 2 用户和用户组 3 查看权限控制信息 4 修改权限控制 4.1 chmod命令 4.2 chown命令 1 root用户 1.1 su root用户即超级管理员 su [-] [用户名] 切换到root用户&#xff0c;exit退回普通用户从 -&#xff1a;可选&#xff0…

社会网络分析工具—— Gephi 或 NetworkX的简单介绍和比较(源自GPTchat)

文章目录我的原始需求两个工具介绍二者比较下载和使用后续 使用教程我的原始需求 如何对不同认知课堂的教师提问行为序列进 行社会网络分析&#xff0c;计算不同认知层级提问行为的中间 中心度和接近中心度&#xff0c; 在进行社会网络分析时&#xff0c;您首先需要收集数据并…

ArcGIS基础:栅格转ASCII校正简单栅格坐标

【校正栅格坐标】 有一些数据量比较小的栅格数据&#xff0c;位置发生了偏移&#xff0c;可以使用【转换工具】对其位置进行校正。 先看一下原始数据&#xff1a; 有2个栅格数据&#xff0c;如下所示&#xff0c;两个数据本身是一个数据&#xff0c;只不过发生了偏移&#x…

java+ssh+mysql银行收银管理系统

项目介绍&#xff1a; 本系统为基于jspmysql的银行管理系统&#xff0c;包含业务员、管理员登录权限&#xff0c;功能如下&#xff1a; 业务员&#xff1a;可以银行系统&#xff0c;可以查看所有客户账户信息、可以新开账户、销户、修改账户信息、存款、取款、转账等功能。 …

C51——通过震动传感器模块让继电器的灯亮起来

继电器触发 模块可以通过跳线设置高电平触发或者低电平触发&#xff08;默认&#xff09; 首先明确继电器的工作逻辑 怎么控制“闭合”开关呢 怎么控制“断开”开关呢 NO口 是常开端 NC 常闭端 COM 公共端 通过IO口向继电器发出低电平 &#xff0c;使得COM口和NO口连接&…

05. XSS漏洞利用

05. XSS漏洞利用 XSS漏洞利用&#xff08;上&#xff09; 获取cookie 什么是cookie&#xff1f; **定义&#xff1a;**cookie是指某些网站为了辨别用户身份而储存在用户本地终端&#xff08;Client Side&#xff09;上的数据&#xff08;通常经过加密&#xff09; **作用&…

jsp+ssm计算机毕业设计宠物医院信息管理系统【附源码】

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JSPSSM mybatis Maven等等组成&#xff0c;B/S模式 Mave…

垃圾回收相关概念

文章目录1. System.gc()的理解2.内存溢出与内存泄漏3. Stop The World4. 并发与并行5. 安全点与安全区域的说明6. 强引用、软引用、弱引用、虚引用1. System.gc()的理解 2.内存溢出与内存泄漏 3. Stop The World 4. 并发与并行 5. 安全点与安全区域的说明 6. 强引用、软引用、弱…

jsp+ssm计算机毕业设计大学生家教服务推荐系统【附源码】

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JSPSSM mybatis Maven等等组成&#xff0c;B/S模式 Mave…

nuxt.js如何将访问的外部ip修改为本地ip? Do you want Code to open the external website?

问题描述&#xff1a; 提示&#xff1a;Do you want Code to open the external website? 译文&#xff1a;是否希望代码打开外部网站&#xff1f; 说明我们nuxt.js访问的是别人的ip地址&#xff0c;而并不是自己的ip 问题解决&#xff1a; 方法一&#xff1a; 查看packa…

Python中GDAL批量绘制多时相栅格遥感影像的像元时间序列曲线图

本文介绍基于Python中gdal模块&#xff0c;对大量多时相栅格图像&#xff0c;批量绘制像元时间序列折线图的方法。 首先&#xff0c;明确一下本文需要实现的需求&#xff1a;现有三个文件夹&#xff0c;其中第一个文件夹存放了某一研究区域原始的多时相栅格遥感影像数据&#x…

C/C++socket网络编程

目录tcp和udp通信流程图socket函数bind函数listen函数accept函数connect函数recv、recvfrom、read函数send、write、sendto、sendmsg函数close、shutdown函数htonl、ntohl、htons、ntohs本地主机和网络字节序转换inet_addr、inet_aton、inet_ntop&#xff0c;IP地址转换函数set…

Spark-概述+快速上手+运行环境

文章目录概述Spark and HadoopSpark or Hadoop核心模块快速上手Spark运行环境Local(本地)Standalone模式搭建和使用提交参数说明配置历史服务配置高可用&#xff08;HA&#xff09;Yarn模式K8S & Mesos 模式部署模式对比端口号概述 Spark 是一种基于内存的快速、通用、可扩…

红米Note7pro安装TWRP及安装PixelExperience系统

参考&#xff1a;https://www.youtube.com/watch?vjB9ksQrxr20&ab_channelTechnologyVikram 所需文件&#xff1a; 一. youtube:Vikram--OTG优盘 (https://www.youtube.com/watch?vjB9ksQrxr20&ab_channelTechnologyVikram) 1.刷入TWRP a. 准备工作&#xff1a;打开…

MR案例:学生排序

排序一、提出任务二、完成任务&#xff08;一&#xff09;准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录&#xff08;二&#xff09;实现步骤1、创建学生实体类2、创建学生映射器类3、创建学生归并器类4、创建学生驱动器类5、启动学生驱动器类&#xff0c;查看结…

JVM虚拟机简介

、 什么是JVM&#xff1f; JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指…

IDEA maven 向项目添加模块时出错创建项目失败

原因一&#xff1a;Maven 版本太新 || Java 版本选择了 JAVA 18 选择 java 版本为1.8构建 即可成功&#xff0c;第一次maven项目建立的时候下图红框内容如图即可 原因二&#xff1a;IDEA 的 maven插件 没有加载完成 通常发生在重设 maven 路径|仓库之后 原因三&#xff1a;mav…