单Model场景下MongoDB的bulkWrite与deleteMany操作有差异吗
两种写法的差异对比
执行效果
两者完全一致,都会删除所有满足user = 对应用户ID的文档,返回的删除条数、异常处理逻辑没有任何区别。
性能表现
两者性能几乎没有可感知的差异:
- 当bulkWrite仅传入1个DeleteManyModel时,客户端只会多出来极少量的列表封装、序列化开销,这部分开销和删除500万条数据的总耗时相比可以完全忽略不计。
- 服务端执行逻辑完全一致:MongoDB不会因为你用了bulkWrite就对单个DeleteMany操作做特殊处理,两种写法会走完全相同的查询计划、加锁逻辑、磁盘写入逻辑,执行耗时基本一致。
生产环境删除500万条数据的优化建议
不管你用上面哪种写法,一次性删除500万条数据都会产生大量的IO、占用写入锁,很容易导致生产库CPU飙高、主从延迟,建议调整为分批删除的逻辑,避免影响线上业务:
Bson deleteFilter = eq("user", user.getId()); // 每批删除2000条,可根据实际业务情况调整批次大小 int batchSize = 2000; while (true) { // 先查询当前批次要删除的文档主键 List<ObjectId> toDeleteIds = getCollection().find(deleteFilter) .projection(Projections.id()) .limit(batchSize) .into(new ArrayList<>()) .stream() .map(doc -> doc.getObjectId("_id")) .toList(); if (toDeleteIds.isEmpty()) { break; } // 执行当前批次删除 getCollection().deleteMany(in("_id", toDeleteIds)); // 每删完一批休眠300ms,降低对生产负载的影响 Thread.sleep(300); }
额外注意事项:
- 提前确认
user字段已经创建了索引,避免全表扫描拖垮数据库。 - 尽量选择业务低峰时段执行删除操作。
内容的提问来源于stack exchange,提问作者krizajb
相关产品推荐
相关产品推荐

