0

我试图在 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
4

2 回答 2

2

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

于 2012-05-10T10:44:21.067 回答
0

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

SELECT FROM contacts WHERE list_id = 100

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

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

    删除联系人 WHERE list_id = 100 LIMIT 1000

  • 删除索引(list_id 除外)、删除、重新创建索引。每次删除时,MySql 都必须重建索引。

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

    更新联系人 SET 已删除 = true WHERE list_id = 100

  • 尝试另一个存储引擎 (MyISAM)

于 2012-05-10T11:08:57.640 回答