MongoDB删数据---一个无聊的测试

2021-11-09 11:19:12 浏览数 (1)

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()

代码语言:javascript复制
---------删除一条记录--------
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方法可以删除单个文档

0 人点赞