为什么删除mongodb中的多个文档要比删除mysql中的多行快得多

时间:2012-05-10 10:28:34

标签: mysql mongodb mongodb-php

我尝试在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中删除满足此条件的所有100K行需要大约99秒。

索引用于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

2 个答案:

答案 0 :(得分:1)

没有数字和细节的毫无意义的问题。很明显,从RDBMS中删除东西可能会更昂贵,因为事务完整性,处理外键等比MongoDB更昂贵。尤其是MongoDB即将发射,你不会注意到操作何时没有完成

答案 1 :(得分:0)

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

SELECT FROM contacts WHERE list_id = 100

如果它快,那么一些常用的方法就是

  • 只要rows_affected为>就会以块的形式删除0

    DELETE FROM contacts WHERE list_id = 100 LIMIT 1000

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

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

    更新联系人SET deleted = true WHERE list_id = 100

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