每次我们使用MongoDB删除大量数据时collection.remove()
,这会使数据库变得非常慢,最终导致我们的Web服务器停机.我相信这是因为删除操作会将集合锁定更长的时间.
我们有一个查询,它为我们提供了我们想要删除的所有文档.但是查询不包含日期/时间字段,因此我们不能使用TTL索引.
有没有办法以某种方式删除数据,nice
不时释放锁定?
Mar*_*erg 20
批量操作可能对此有所帮助.无序bulk.find(queryDoc).remove()
基本上是db.collection.remove(queryDoc)
针对大量操作进行优化的版本.它的用法非常简单:
var bulk = db.yourCollection.initializeUnorderedBulkOp()
bulk.find(yourQuery).remove()
bulk.execute()
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅MongoDB文档中的Bulk.find().remove().
这种方法背后的想法不是加快移除速度,而是减少负载.在我的测试中,负载减少了一半,时间比a减少了一些db.collection.remove(query)
.
但是,删除操作不应该将您的实例陈旧到冻结点.我在我5岁的MacBook上测试了12M文件的删除情况,虽然它给它带来了一些负担,但它远远没有冻结,花了大约10分钟.但是,我用于查询的字段已编入索引.
这导致我得出的结论是,您可能正在体验集合扫描.如果我是对的,则会发生以下情况:您的查询包含未包含在索引中或无法构造索引交集的字段或字段组合.这迫使有问题的mongod 从磁盘中查找,访问和读取数据库中每个文档的 那些字段.
因此,在删除操作之前在后台创建包含查询中每个字段的索引可能会有所帮助,但这是违反直觉的.
db.collection.createIndex(
{firstFieldYouQueryBy:1,...,NthFieldYouQueryBy:1},
{background:true}
)
Run Code Online (Sandbox Code Playgroud)
虽然这个操作将在后台完成,但shell会阻塞.这可能需要一段时间.您可以通过打开第二个shell来查看状态并使用:
db.currentOp()
Run Code Online (Sandbox Code Playgroud)
(你需要搜索一下).
创建索引(您可以使用它来检查db.collection.getIndices()
)时,删除操作应该更有效,因此更快.完成批量删除后,如果不需要,您当然可以删除索引.
使用索引,可以防止收集扫描,从而大大加快了删除速度.
显而易见的是,首先创建索引并在索引准备好后发出bulk命令是有意义的.
归档时间: |
|
查看次数: |
10518 次 |
最近记录: |