我正在从事一个涉及大量数据库写入的项目(70%的插入和30%的读取)。这个比率还包括我认为是一个读一个写的更新。读取可能是脏的(例如,在读取时我不需要100%准确的信息)。 该任务每小时将处理超过100万个数据库事务。

我在网上读了一堆关于MyISAM和InnoDB之间区别的东西,对于我将用于这个任务的特定数据库/表来说,MyISAM似乎是显而易见的选择。从我看来,InnoDB在需要事务时是很好的,因为它支持行级锁。

有人有这种负载(或更高)的经验吗?MyISAM是正确的选择吗?


当前回答

有点偏离主题,但为了文档的目的和完整性,我想添加以下内容。

一般来说,使用InnoDB会使应用程序变得不那么复杂,可能也更没有bug。因为可以将所有引用完整性(外键约束)放入数据模型中,所以不需要像使用MyISAM时那样多的应用程序代码。

Every time you insert, delete or replace a record, you will HAVE to check and maintain the relationships. E.g. if you delete a parent, all children should be deleted too. For instance, even in a simple blogging system, if you delete a blogposting record, you will have to delete the comment records, the likes, etc. In InnoDB this is done automatically by the database engine (if you specified the contraints in the model) and requires no application code. In MyISAM this will have to be coded into the application, which is very difficult in web-servers. Web-servers are by nature very concurrent / parallel and because these actions should be atomical and MyISAM supports no real transactions, using MyISAM for web-servers is risky / error-prone.

而且在大多数情况下,InnoDB会表现得更好,原因有很多,其中一个原因是它能够使用记录级锁而不是表级锁。不仅在写比读更频繁的情况下,在大型数据集上有复杂连接的情况下也是如此。我们注意到,对于非常大的连接(需要几分钟),使用InnoDB表比MyISAM表性能提高了3倍。

我想说的是,在使用MySQL时,InnoDB(使用3NF数据模型,具有引用完整性)应该是默认的选择。MyISAM只能在非常具体的情况下使用。它很可能会执行更少,导致应用程序更大,bug更多。

话虽如此。数据模型是一门很少在网页设计师/程序员中发现的艺术。无意冒犯,但这确实解释了MyISAM被如此广泛使用的原因。

其他回答

我曾经在一个使用MySQL的大容量系统上工作过,我也尝试过MyISAM和InnoDB。

我发现MyISAM中的表级锁定对我们的工作负载造成了严重的性能问题,这听起来与您的工作负载类似。不幸的是,我还发现在InnoDB下的性能也比我希望的要差。

最后,我通过分割数据解决了争用问题,这样插入就进入了一个“热”表,而选择从不查询热表。

这也允许删除(数据是时间敏感的,我们只保留X天的价值)发生在“陈旧”的表上,这些表同样不会被选择查询触及。InnoDB在批量删除方面的性能似乎很差,所以如果你打算清除数据,你可能想要以这样一种方式来构造它,即旧数据在一个陈旧的表中,可以简单地删除而不是对其进行删除。

当然,我不知道你的应用程序是什么,但希望这能让你对MyISAM和InnoDB的一些问题有一些了解。

如果使用MyISAM,则每小时不会执行任何事务,除非将每个DML语句视为一个事务(在任何情况下,在崩溃时都不是持久的或原子的)。

因此我认为你必须使用InnoDB。

每秒300个交易听起来很多。如果您绝对需要这些事务在电源故障时保持持久,请确保您的I/O子系统能够轻松地处理每秒这么多的写操作。您至少需要一个带有电池缓存的RAID控制器。

如果你可以降低一点持久性,你可以使用InnoDB,将innodb_flush_log_at_trx_commit设置为0或2(参见文档),你可以提高性能。

有许多补丁可以从谷歌和其他补丁中提高并发性——如果没有它们仍然不能获得足够的性能,这些补丁可能会引起您的兴趣。

这个问题和大部分答案都已经过时了。

是的,MyISAM比InnoDB快是无稽之谈。注意问题的日期:2008年;现在已经过去了近十年。从那时起,InnoDB在性能上取得了显著的进步。

戏剧性的图表是MyISAM获胜的一种情况:没有where子句的COUNT(*)。但这真的是你花时间做的事情吗?

如果你运行并发测试,InnoDB很可能会赢,即使是对MEMORY。

如果在对select进行基准测试时执行任何写入操作,MyISAM和MEMORY可能会因为表级锁定而丢失。

事实上,Oracle非常确定InnoDB更好,以至于他们几乎从8.0中删除了MyISAM。

这个问题写于5.1的早期。从那时起,这些主要版本被标记为“一般可用性”:

2010: 5.5(。12月8日) 2013: 5.6(。2月10日) 2015年:5.7(。10月9日) 2018年:8.0(。四月十一日)

底线:不要使用MyISAM

我尝试在MyISAM和InnoDB表中插入随机数据。结果相当令人震惊。MyISAM插入100万行的时间比InnoDB插入1万行的时间少几秒钟!

我发现即使Myisam有锁争用,它在大多数情况下仍然比InnoDb快,因为它使用了快速的锁获取方案。我尝试了几次Innodb,总是因为这样或那样的原因回到MyIsam。此外,InnoDB在巨大的写负载下会非常消耗CPU。