MongoDB删数据---一个无聊的测试
上周五的时候,线上的一个MongoDB集群需要删除部分数据,这个MongoDB集群本身是个分片集群,包含10个分片,架构如下:
集群的总体节点情况如下:
15个mongos
5个mongoc
10个分片,每个分片7副本
在这样的一个集群上,需要删除一个集合的部分数据,包含数据记录977w条,删除的条件是分片键。业务给出的待删除记录为:
db.test.find({pid:xxxxxxx})
其中,pid是集合的分片键。
分析:
因为是按照分片键进行删除,所以如果我们执行一条删除语句,理论上会将删除的请求分发到每个shard上,然后分别执行删除操作,最后汇总起来。
实际操作过程中,我们采用的删除语句如下:
db.test.remove({pid:xxxxxxx})
实际执行时间:977w满足条件的数据全部删除,总计不到2分钟。(这个时间具有参考意义,大家可以记录下)
延伸
这里,就出现了一个问题,在MongoDB中,常用的删除语句有2中,分别是deleteMany语法和remove语法,那么这两种语法,到底哪个更快一点,更高效呢?
我们先来分析这两个语法:
首先:db.collection.deleteMany
()
这个语法的使用方法如下:
代码语言:javascript复制db.collection.deleteMany(
<filter>,
{
writeConcern: <document>,
collation: <document>
}
)
其中:
filter写条件,如果删除所有文档,则写{}即可;
writeConcern、collation写具体的删除配置,也可以不写。
返回值:
返回一个文档,包含一个acknowledged
字段,如果在writeConcern条件下操作成功,则为true,如果操作失败,则为false;另外有一个deletedCount字段,包含删除的文档记录条数
再来看:db.collection.remove
()
---------删除一条记录--------
db.collection.remove(
<query>,
<justOne>
)
----------删除多条记录------
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>,
collation: <document>
}
)
相比deleteMany,remove方法多了个选项,有一个bool类型的justOne选项,如果设置为true,则只删除满足条件的一条文档。
deleteMany方法无法实现只删除一条文档,如果非要实现,请使用db.collection.deleteOne方法。
那么这两个语法,到底哪个高效呢?下面我简单做了个实验:
1、给test、test1两个集合分别插入20w条数据;
2、分别使用deleteMany和remove方法删除大于1000的记录,总计包含19w多;
3、记录操作开始时间和结束时间,对比整体的时间消耗。
得到的实验结果如下:
代码语言:javascript复制--------------remove方法测试------------
test1:PRIMARY> for (var i=1 ;i<=200000 ; i ){ db.test.insert({"number":i})}
WriteResult({ "nInserted" : 1 })
---开始时间
test1:PRIMARY> new Date()
ISODate("2021-11-02T06:29:09.995Z")
test1:PRIMARY> db.test.remove({'number':{$gt:1000}})
WriteResult({ "nRemoved" : 199000 })
---结束时间
test1:PRIMARY> new Date()
ISODate("2021-11-02T06:29:25.412Z")
remove总计时间:15.417s
--------------deleteMany方法测试------------
test1:PRIMARY> for (var i=1 ;i<=200000 ; i ){ db.test1.insert({"number":i})}
WriteResult({ "nInserted" : 1 })
---开始时间
test1:PRIMARY> new Date()
ISODate("2021-11-02T06:48:08.511Z")
test1:PRIMARY> db.test1.deleteMany({'number':{$gt:1000}})
{ "acknowledged" : true, "deletedCount" : 199000 }
---结束时间
test1:PRIMARY> new Date()
ISODate("2021-11-02T06:48:24.204Z")
deleteMany总计时间:15.693s
总体来看:
1、deleteMany和remove方法删除数据的效率差不多。
2、deleteMany语法执行完成之后,会告知执行是否失败,并告知记录条数;而remove方法执行之后,只给出记录条数。
3、deleteMany语法无法删除一个文档,而remove方法可以删除单个文档