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

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

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


当前回答

我知道这不会受欢迎,但我还是这么说:

myISAM缺乏对数据库基本要素的支持,如事务和引用完整性,这通常会导致应用程序出现故障/ bug。如果您的数据库引擎甚至不支持这些基础知识,那么您不可能不学习正确的数据库设计基础知识。

在数据库世界中不使用引用完整性或事务就像在软件世界中不使用面向对象编程一样。

InnoDB已经存在了,使用它吧!尽管myISAM是所有遗留系统的默认引擎,但MySQL开发人员最终还是同意在新版本中将其更改为默认引擎。

不,无论您是在读写还是有什么性能考虑,使用myISAM都会导致各种各样的问题,比如我刚刚遇到的这个问题:我正在执行数据库同步,同时其他人访问了一个访问myISAM表的应用程序。由于缺乏事务支持,这个引擎的可靠性也很差,导致整个数据库崩溃,我不得不手动重启mysql!

在过去15年的开发中,我使用了许多数据库和引擎。在此期间,myISAM在我身上崩溃了十几次,其他数据库只有一次!那是一个microsoft SQL数据库,其中一些开发人员编写了错误的CLR代码(公共语言运行时-基本上是在数据库内部执行的c#代码),顺便说一下,这并不是数据库引擎的错误。

我同意这里的其他答案,即高质量的高可用性、高性能应用程序不应该使用myISAM,因为它不起作用,它不够健壮或不够稳定,无法带来无挫折的体验。详见Bill Karwin的回答。

附注:我喜欢myISAM的粉丝们投反对票,但不能告诉你这个答案的哪一部分是错误的。

其他回答

人们经常谈论性能、读写、外键等等,但在我看来,存储引擎还有一个必须具备的特性:原子更新。

试试这个:

Issue an UPDATE against your MyISAM table that takes 5 seconds. While the UPDATE is in progress, say 2.5 seconds in, hit Ctrl-C to interrupt it. Observe the effects on the table. How many rows were updated? How many were not updated? Is the table even readable, or was it corrupted when you hit Ctrl-C? Try the same experiment with UPDATE against an InnoDB table, interrupting the query in progress. Observe the InnoDB table. Zero rows were updated. InnoDB has assured you have atomic updates, and if the full update could not be committed, it rolls back the whole change. Also, the table is not corrupt. This works even if you use killall -9 mysqld to simulate a crash.

性能当然是可取的,但不丢失数据更重要。

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

是的,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

对于这样的读写比率,我猜InnoDB会表现得更好。 既然您可以接受脏读,那么您可以(如果您负担得起)复制到一个从服务器,并让您的所有读都到从服务器。另外,考虑批量插入,而不是一次插入一条记录。

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

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

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

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

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

几乎每次我开始一个新项目时,我都会问同样的问题,看看我是否能想出新的答案。

它最终归结为——我使用最新版本的MySQL并运行测试。

我有表,我想做键/值查找…就这些。我需要得到一个哈希键的值(0-512字节)。这个数据库上没有很多事务。表偶尔会更新(整个表),但是没有事务。

所以我们这里讨论的不是一个复杂的系统,我们讨论的是一个简单的查找,..以及如何(除了使表RAM常驻)优化性能。

我也在其他数据库(即NoSQL)上做测试,看看是否有任何地方我可以获得优势。我所发现的最大优势是键映射,但就查找而言,MyISAM目前是所有优势中的佼佼者。

虽然,我不会执行与MyISAM表的金融交易,但对于简单的查找,你应该测试它。通常是2倍到5倍的查询/秒。

试试吧,我欢迎辩论。