今天通过一个实验比较了一下MongoDB和MySQL的性能,注意这个比较只反映了我们这个应用场景下的情况,并不能代表普遍的情况。
我们希望存储一些视频历史上的流量,需要存1年的时间,每天活跃的视频在百万数量级,流量用整型表示就可以了。在我们的应用中,写性能是优先考虑的因素,所以第一步的实验主要比较写入的性能,由于存储的数据是被单一应用(进程)独享的,sqlite也满足我们的应用场景,因此我们同时也测试了sqlite的写入性能。
实验环境:
单台服务器 RHEL 5.5 64bit,双核 Intel(R) Xeon(R) CPU 5130 @ 2.00GHz CPU,8G内存,本地磁盘。
测试程序(python):
MySQL: MySQLdb
Sqlite: pysqlite2
MongoDB: pymongo
DB Schema:
1. MySQL (InnoDB) & Sqlite:
CREATE TABLE `inventory` (
`date` DATE NOT NULL,
`id` INT(11) NOT NULL,
`views` INT(11) NOT NULL,
PRIMARY KEY (`date`, `id`));
2. MongoDB index
inventory.create_index([('date',ASCENDING), ('id',ASCENDING)], unique=True, dropDups=True)
测试方法:
在我们的应用场景中,会随机地插入或更新任意一个item上今天的流量。因此我们测试按id随机顺序插入和更新,首先插入一百万条数据,然后再更新这一百万条数据。对于MongoDB,插入和更新都用update方法:
inventory.update({'date':date, 'id':id}, {'$inc':{'views':1000}}, True)
测试结果:
其中MySQL和Sqlite的结果是在以128K条数据为一个transaction批量插入和更新的条件下得到的,如果改为一条一条插入和更新,MySQL的插入和更新时间增加约30%,而Sqlite的性能则下降到无法接受,参见我前面的一个测试 。看来这样使用MongoDB的性能并不是太好,还需要进一步测试在我们的应用场景下如何使用MongoDB才能提高性能。
测试 | MySQL | Sqlite | MongoDB |
---|---|---|---|
随机插入一百万条记录 | 377秒 | 125秒 | 1378秒 |
随机更新一百万条记录 | 411秒 | 158秒 | 1405秒 |