【MongoDB】MongoDB中如何删除一张大表中的数据?

MongoDB testDB库 test表数据结构如下:

{
    "_id" : "5d6f830fd08e7055ff48613c",
    "xxx" : "xxxxxx",
    "xxx" : "xxxxxx",
    "time" : ISODate("2019-09-04T09:25:35.350Z"),
    "type" : "xxxxxx",
    "xxx" : "xxxxxx",
    "xxx" : "xxxxxx",
    "userAgent" : "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36"
}

如果要删除此表半年前的大概4亿条数据,是否会阻塞数据库?

删除4亿条数据可能会对数据库性能产生一定的影响,并且可能导致数据库阻塞。

为了避免这种情况,可以考虑采用分批删除的方法,将删除操作分成多个较小的批次进行。

以下是一种分批删除的方法:

  1. 确定每个批次要删除的数据量,例如每个批次删除100万条数据。
  2. 使用一个循环结构,每次迭代删除一个批次的数据,直到删除完所有数据。
  3. 在每个批次删除之间添加适当的延迟,以降低对数据库的负载。

以下是一个示例的代码片段,用于分批删除数据:

var batchSize = 1000000; // 每个批次要删除的数据量
var totalCount = db.test.count({ time: { $lt: new Date("2019-03-04T09:25:35.350Z") } }); // 要删除的总数据量
var batches = Math.ceil(totalCount / batchSize); // 计算总共需要的批次数

for (var i = 0; i < batches; i++) {
  db.test.deleteMany({ time: { $lt: new Date("2019-03-04T09:25:35.350Z") } }, { limit: batchSize });
  sleep(1000); // 添加适当的延迟,以降低对数据库的负载
}

这段代码会将删除操作分成多个批次,每个批次删除指定数量的数据,并在每个批次之间添加1秒的延迟。

请注意,根据您的具体情况,您可能需要根据数据库的性能和资源限制来调整批次大小和延迟时间。此外,建议在非高峰期执行此操作,并确保在执行之前进行适当的备份和测试。

time 字段没有索引,对删除有什么影响吗?

如果time字段没有索引,对删除操作可能会产生较大的性能影响。在执行删除操作时,数据库需要扫描整个集合来找到满足删除条件的文档。对于包含4亿条数据的集合,这将需要耗费大量的时间和系统资源。

没有索引的情况下,删除操作的性能取决于集合的大小和硬件资源。删除大量数据可能会导致数据库阻塞,影响其他查询和操作的性能。

如果可能的话,强烈建议在执行删除操作之前为time字段创建一个索引。通过为time字段创建索引,可以大大提高删除操作的性能,减少对数据库的影响。

可以使用以下命令为time字段创建升序索引:

db.test.createIndex({ time: 1 },{background: true})

请注意,为大型集合创建索引可能需要一些时间和系统资源,因此建议在非高峰期执行该操作,并确保在执行之前进行适当的备份和测试。

给 time 字段加上索引,有多大意义?

time字段添加索引可以带来多个好处:

  1. 提高查询性能:当您在查询中使用time字段作为筛选条件时,索引可以帮助数据库快速定位满足条件的文档,减少扫描的文档数量,从而提高查询性能。

  2. 加速排序操作:如果您需要按照time字段进行排序,索引可以加速排序操作,避免对整个集合进行排序,从而提高排序性能。

  3. 优化范围查询:如果您需要执行范围查询,例如查找某个时间段内的文档,索引可以帮助快速定位和筛选满足条件的文档,加快查询速度。

  4. 减少数据库负载:通过使用索引,数据库可以更高效地执行查询操作,减少了全表扫描的需求,从而降低了数据库服务器的负载。

总之,为time字段添加索引可以显著提高查询性能和排序性能,并减少数据库负载。特别是在对time字段进行频繁的查询和范围查询时,索引的作用更为明显。请注意,索引可能会增加一些存储空间和写入性能的开销,因此需要根据具体的业务需求进行权衡和优化。

如何要设置此表此后自动保持最近半年数据,该如何操作?

要设置表自动保留最近半年的数据,可以使用TTL(Time-To-Live)索引来实现。TTL索引允许您为文档的某个字段设置过期时间,一旦过期,MongoDB会自动删除这些文档。

以下是实现自动保留最近半年数据的操作:

  1. 创建一个TTL索引,并设置过期时间为半年(以秒为单位):
db.test.createIndex({ "time": 1 }, { expireAfterSeconds: 15778463, background: true })

这将为time字段创建一个TTL索引,并设置过期时间为15778463秒(半年)。

  1. 确保在插入文档时,time字段包含一个日期值。确保插入的文档中time字段使用ISO日期格式。
db.test.insertOne({ "time": ISODate("2022-01-01T00:00:00Z") })
  1. 确保MongoDB后台进程运行,并且时间轮询程序在后台定期检查并删除过期的文档。

MongoDB会自动处理过期文档的删除操作,您无需手动删除。

请注意,TTL索引是基于时间的删除机制,其精度可能有所偏差。因此,删除操作可能不会在过期时立即发生,而是在后续的时间轮询中进行删除。此外,TTL索引可能会对数据库性能产生一定的影响,请根据您的具体情况进行评估和测试。

如果我对 test表使用 db.test.createIndex({ time: 1 },{background: true}) 创建过索引,如何再执行 db.test.createIndex({ "time": 1 }, { expireAfterSeconds: 15778463, background: true }) ?

如果您已经对test表的time字段创建了一个普通索引(db.test.createIndex({ time: 1 }, { background: true })),然后想要进一步创建一个TTL索引,您可以执行以下操作:

db.test.dropIndex({ time: 1 }) // 删除现有的普通索引
db.test.createIndex({ "time": 1 }, { expireAfterSeconds: 15778463, background: true }) // 创建TTL索引

首先,使用db.test.dropIndex({ time: 1 })删除现有的普通索引。然后,使用db.test.createIndex({ "time": 1 }, { expireAfterSeconds: 15778463, background: true })创建TTL索引。

通过这样的操作,您首先删除了现有的索引,然后创建了一个新的TTL索引。请注意,删除索引和创建索引的操作可能会对数据库的性能产生一定的影响,请在非高峰期执行,并确保在执行之前进行适当的备份和测试。

在MongoDB中,db.collection.dropIndex()操作默认是阻塞的,它会阻塞其他数据库操作直到索引删除完成。目前,MongoDB没有提供类似background: true的参数来在后台删除索引。

请注意,删除索引和创建索引的操作可能会对数据库的性能产生一定的影响,请在非高峰期执行,并确保在执行之前进行适当的备份和测试。

在MongoDB中,db.collection.dropIndex()操作默认是阻塞的,它会阻塞其他数据库操作直到索引删除完成。目前,MongoDB没有提供类似background: true的参数来在后台删除索引。
这里的 阻塞其他数据库操作 ,具体是阻塞什么操作?

在MongoDB中,当执行db.collection.dropIndex()操作删除索引时,它会阻塞以下操作:

  1. 同一集合上的其他写操作:删除索引的操作可能会导致对集合的写操作(如插入、更新、删除)被阻塞,直到索引删除成功为止。

  2. 对该索引的查询操作:如果有查询正在使用被删除的索引,它们可能会被阻塞,直到索引删除成功为止。

  3. 其他需要修改索引元数据的操作:例如,修改索引选项或重建索引等操作可能会等待删除索引的操作完成。

需要注意的是,索引删除操作的阻塞是相对较短暂的,通常不会对数据库的整体性能产生显著的影响。但在某些情况下,如果集合中包含大量文档或索引较大,删除索引可能需要一些时间和系统资源。

为了最小化对数据库操作的阻塞影响,建议在非高峰期执行索引删除操作,并确保在执行之前进行适当的备份和测试。对于大型集合或需要频繁删除索引的情况,可以考虑在进行索引删除时,通过复制集群或分片集群来提供高可用性和负载均衡。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容