MongoDB不比MySQL快吗?

9 投票
3 回答
8606 浏览
提问于 2025-04-17 02:45

几个月前我发现了mongodb,读完这篇文章后,我觉得mongodb真的比mysql快,所以我决定自己做个测试。问题是,我得到的结果和那篇文章的作者不一样,尤其是在查询数据库时:mongodb似乎比MyISAM表还慢。你能看看我的python代码吗?可能里面有什么问题:

from datetime import datetime
import random
import MySQLdb
import pymongo

mysql_db=MySQLdb.connect(user="me",passwd="mypasswd",db="test_kv")
c=mysql_db.cursor()

connection = pymongo.Connection()
mongo_db = connection.test
kvtab = mongo_db.kvtab

nb=1000000
thelist=[]
for i in xrange(nb):
    thelist.append((str(random.random()),str(random.random())))
t1=datetime.now()

for k,v in thelist:
    c.execute("INSERT INTO key_val_tab (k,v) VALUES ('" + k + "','" + v + "')")

dt=datetime.now() - t1
print 'MySQL insert elapse :',dt

t1=datetime.now()
for i in xrange(nb):
    c.execute("select * FROM key_val_tab WHERE k='" + random.choice(thelist)[0] + "'")
    result=c.fetchone()

dt=datetime.now() - t1
print 'MySQL select elapse :',dt


t1=datetime.now()

for k,v in thelist:
    kvtab.insert({"key":k,"value":v})

dt=datetime.now() - t1
print 'Mongodb insert elapse :',dt
kvtab.ensure_index('key')
t1=datetime.now()
for i in xrange(nb):
    result=kvtab.find_one({"key":random.choice(thelist)[0]})

dt=datetime.now() - t1
print 'Mongodb select elapse :',dt

注意事项:

  • MySQL和mongodb都在本地运行。
  • MySQL和mongodb的'key'列都已经建立了索引。

MySQL表:

CREATE TABLE IF NOT EXISTS `key_val_tab` (
  `k` varchar(24) NOT NULL,
  `v` varchar(24) NOT NULL,
  KEY `kindex` (`k`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

版本信息:

  • MySQL: 5.1.41
  • mongodb : 1.8.3
  • python : 2.6.5
  • pymongo : 2.0.1
  • Linux : Ubuntu 2.6.32 32位带PAE
  • 硬件 : 桌面核心i7 2.93 GHz

结果(针对100万次插入/查询):

MySQL insert elapse : 0:02:52.143803
MySQL select elapse : 0:04:43.675914
Mongodb insert elapse : 0:00:49.038416  -> mongodb much faster for insert
Mongodb select elapse : 0:05:10.409025  -> ...but slower for quering (thought was the opposite)

3 个回答

2

看执行时间来判断数据库的好坏是不对的。每次请求至少包含三个部分:

  • 请求准备(客户端),
  • 请求执行(服务器),
  • 响应准备(客户端)

根据我的经验,把数据从MongoDB转到Python要花的时间比从MySQL转到Python多得多。

另外,你在这两种数据库中都应该使用索引。MongoDB只有在你查询的字段上有索引时才能表现良好。至于MySQL,我觉得在innoDB上测试性能更好,因为MyISAM不支持事务、外键和触发器,对我来说有点过时了。

7
MySQL insert elapse : 0:02:52.143803
Mongodb insert elapse : 0:00:49.038416  -> mongodb much faster for insert

Mongodb的插入速度很快,因为它会把所有数据先放到内存里,然后再定期把这些数据写到硬盘上。

MySQL select elapse : 0:04:43.675914
Mongodb select elapse : 0:05:10.409025  -> ...but slower for quering (thought was

如果你把数据嵌入或者去规范化,使用mongodb时能获得最佳性能。在很多情况下,mongodb让我们可以避免使用连接查询,因为数据是嵌入的或去规范化的。

而当你只是往一个集合(表)里插入数据,并通过索引读取数据时,mongodb的速度并不会比sql数据库快,读取速度大致是一样的。

顺便提一下:在mongodb 2.0版本中,索引的速度提高了25%,所以我猜2.0的速度会比mysql快。

31

唉,这种基准测试,虽然我用这个词有点宽泛,通常从一开始就不太靠谱。MySQL并不是比MongoDB“慢”的数据库。一个是关系型数据库,另一个是NoSQL文档存储。它们在各自设计的功能领域里应该是更快的。就MySQL(或任何关系数据库管理系统)和MongoDB来说,它们的重叠部分并没有很多,很多人对此的假设其实是错误的。这就像把苹果和橘子拿来比较一样,Redis和MongoDB的讨论也是如此。

要考虑的变量太多了(比如应用功能需求、硬件资源、并发、配置、可扩展性等等),所以任何以“MongoDB比MySQL快”或反之的结论,都是在过于泛化结果,几乎没有什么实际意义。

如果你想做基准测试,首先要明确一套严格的功能需求和业务规则,然后在这两种持久化解决方案上尽可能高效地实现它们。结果可能会显示一个比另一个快,但几乎在所有情况下,速度更快的方法都有一些相关的缺点,这可能会让较慢的解决方案在某些需求下更可行。

以上这些都忽略了,前面的基准测试并没有模拟任何真实的场景。实际上,不会有很多应用在没有任何线程/并发的情况下进行最大吞吐量的插入(这对大多数存储解决方案的性能影响很大)。

最后,这样比较插入操作也有点问题。MongoDB可以通过“火并忘”的批量插入实现惊人的插入吞吐量,但如果是fsynced、复制写入的话,速度可能会慢几个数量级。这里的关键是,MongoDB给你提供了选择,而MySQL则没有(或者选择更少)。所以这种比较只有在业务需求允许“火并忘”类型的写入时才有意义(这就是说,“我希望它能成功,但如果不行也没关系”)。

总结一下:别再做简单的吞吐量基准测试了。它们几乎总是没什么用。

撰写回答