【问题标题】:why deleting multiple documents in mongdb is much faster that deleting multiple rows in mysql为什么在 mongodb 中删除多个文档比在 mysql 中删除多行要快得多
【发布时间】:2012-05-18 21:58:06
【问题描述】:

我尝试在 mongodb 和 mysql 中都输入数据。一行有字段 list_id,一个 list_id 可以有很多行。看起来在 mongdb 中删除多个文档比在 mysql 中删除多行要快得多。我在 mysql 中使用 innodb 引擎。 Mysql 和 mongdb 在同一台服务器上。 例如,

DELETE FROM contacts WHERE list_id = 100

慢很多
return self::remove(array('LISTID' => $listId), array('safe' => true));

我在php中对驱动程序使用安全模式,所以它应该等到它删除所有数据。

这里是关于 mongodb 集合的信息:

 "count" : 23456989,
        "size" : 4391452160,
        "avgObjSize" : 187.21295218239646,
        "storageSize" : 5727051776,
        "numExtents" : 32,
        "nindexes" : 2,
        "lastExtentSize" : 961069056,
        "paddingFactor" : 1.0099999999950207,
        "flags" : 1,
        "totalIndexSize" : 2983806672,
        "indexSizes" : {
                "_id_" : 787504144,
                "LISTID_1_EMAIL_1" : 2196302528
        },
        "ok" : 1
}

例如,如果有100K行满足条件,在mongodb中大约快30倍,在mysql中大约需要99秒才能删除所有满足条件的100K行。

mysql 和 mongodb 都使用索引。

EXPLAIN SELECT *
FROM `subscribers`
WHERE list_id =118

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  subscribers     ref     FK_list_id  FK_list_id  4   const   1    

我现在不在线做这个操作,我把数据放到队列里后台做,分块删除数据。

但我想知道为什么删除的时间相差如此之大,大概是 20-30 次。 是不是因为这个操作在 mongodb 中不是原子操作,所以在 mongodb 中删除要快得多?

这就是

SET PROFILING = 1;
DELETE FROM subscribers WHERE list_id = 118;
SHOW PROFILE FOR QUERY 1;

删除 100K 行的显示:

starting    0.000052
checking permissions    0.000000
Opening tables  0.000000
System lock     0.000000
init    0.000000
updating    84.382015
end     0.000006
Waiting for query cache lock    0.000002
end     0.000006
query end   0.035284
closing tables  0.000021
freeing items   0.000040
logging slow query  0.000001
logging slow query  0.000002
cleaning up     0.000002

【问题讨论】:

  • 没有数字和细节的毫无意义的问题。很明显,从 RDBMS 中删除内容可能会更昂贵,因为事务完整性、处理外键等比在 MongoDB 中更昂贵。尤其是 MongoDB 是即发即弃的,当操作未完成时您不会注意到。
  • 在mongodb中使用的是安全模式,所以应该等到删除。
  • 由于您没有说明您使用的是什么引擎(innodb、myisam 或其他),因此很难确切说明原因,但众所周知,Mongo 做的更少并延迟了 fsync-ing,因此提高速度(并且不时丢失记录)。
  • 我在mysql中使用innodb引擎。
  • 问题然后扩展到什么是 InnoDB 的配置值,您在什么硬件上运行它,mongo 与 mysql 等在同一台机器上,但底线是 mongo 通过延迟写入来实现其速度到磁盘。它的 I/O 也比 mysql 少,而且它的 CPU 密集度不高。这里的场景是无穷无尽的,确定发生了什么的最好方法是检查从每个 IO 中删除时正在执行的 IO 数量,这将为您提供答案。

标签: mysql mongodb mongodb-php


【解决方案1】:

没有数字和细节的毫无意义的问题。很明显,从 RDBMS 中删除内容可能会更昂贵,因为事务完整性、处理外键等比在 MongoDB 中更昂贵。尤其是 MongoDB 是一劳永逸的,当操作没有完成时你不会注意到

【讨论】:

  • 在mongodb中使用安全模式,所以应该等到删除。
  • 你想要什么数字和细节?
  • 我有 2 辆车。 A 车比 B 车快 30 倍。你想要什么数字?
  • 在我的问题中我写道,在 mysql 中删除 100K 行大约需要 99 秒。
【解决方案2】:

您可以验证瓶颈是否是查询。这需要多长时间?

SELECT FROM contacts WHERE list_id = 100

如果速度很快,那么一些常用的方法是

  • 只要 rows_affected > 0,就分块删除

    DELETE FROM contacts WHERE list_id = 100 LIMIT 1000

  • 删除索引(list_id 除外)、删除、重新创建索引。 MySql 每次删除都要重建索引。

  • 添加一个逻辑删除列。在您的查询中尊重这一点。运行一个定时删除旧记录的作业。

    UPDATE contacts SET deleted = true WHERE list_id = 100

  • 尝试其他存储引擎 (MyISAM)

【讨论】:

  • 我说那个字段是索引,所以 SELECT FROM contacts WHERE list_id = 100 很快。
  • 在我的问题中我写道我现在不在线进行此操作,我将数据放入队列并在后台执行,按块删除数据,脚本由 cron 运行。问题是为什么mongodb和mysql中删除的时间相差这么大。我不能使用 MyISAM,因为我需要事务,创建的所有索引都是查询数据所必需的。
  • InnoDB 每次插入/更新/删除一行时都需要重建它的索引。对于插入,MySQL 支持INSERT DELAYED ... 命令,它解决了批量插入的这个问题。删除没有类似的东西。由于 InnoDB 使用事务,并且可能发生查询失败,记录 99,999 of 100,00 0 并且 InnoDB 必须回滚完整的事务,这是一项艰巨的任务(假设联系人与on delete cascade 的contact_numbers 有一个 FK-Relation更要回滚。所以尝试一次删除 1000 到 10,000 行之间的内容,这应该会提高速度
  • 我不详细了解mongodb。但我想safe = true 只是意味着,电话会等到工作完成。如果操作在 100,000 中的第 70,000 条记录中失败,会发生什么?是否为已删除的每条记录回滚完整的操作?我想没有。
  • 来自 mongodb 常见问题解答:MongoDB does not use traditional locking or complex transactions with rollback, as it is designed to be lightweight and fast and predictable in its performance. It can be thought of as analogous to the MySQL MyISAM autocommit model. By keeping transaction support extremely simple, performance is enhanced, especially in a system that may run across many servers.
猜你喜欢
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
  • 2015-05-01
相关资源
最近更新 更多