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

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

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


当前回答

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

其他回答

myisam对于这种类型的工作负载(高并发写入)是一个NOGO,我对innodb没有那么多的经验(测试了3次,发现每次性能都很糟糕,但自从上次测试以来已经有一段时间了) 如果你没有被强迫运行mysql,可以考虑尝试postgres,因为它处理并发写要更好

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

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

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

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

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

有点晚了…但这是我几个月前写的一篇相当全面的文章,详细介绍了MYISAM和InnoDB之间的主要区别。喝杯茶(或者一块饼干),好好享受吧。


MyISAM和InnoDB之间的主要区别在于引用完整性和事务。还有其他区别,如锁定、回滚和全文搜索。

参照完整性

Referential integrity ensures that relationships between tables remains consistent. More specifically, this means when a table (e.g. Listings) has a foreign key (e.g. Product ID) pointing to a different table (e.g. Products), when updates or deletes occur to the pointed-to table, these changes are cascaded to the linking table. In our example, if a product is renamed, the linking table’s foreign keys will also update; if a product is deleted from the ‘Products’ table, any listings which point to the deleted entry will also be deleted. Furthermore, any new listing must have that foreign key pointing to a valid, existing entry.

InnoDB是一个关系DBMS (RDBMS),因此具有引用完整性,而MyISAM没有。

事务和原子性

表中的数据使用数据操作语言(DML)语句进行管理,例如SELECT、INSERT、UPDATE和DELETE。事务将两个或多个DML语句组合到一个工作单元中,因此可以应用整个工作单元,也可以不应用任何工作单元。

MyISAM不支持事务,而InnoDB支持。

如果在使用MyISAM表时操作中断,操作将立即中止,受影响的行(甚至是每行中的数据)仍然受到影响,即使操作没有完成。

如果一个操作在使用InnoDB表时被中断,因为它使用事务,具有原子性,任何没有完成的事务都不会生效,因为没有提交。

表锁vs行锁

当对MyISAM表执行查询时,所查询的整个表将被锁定。这意味着后续查询只会在当前查询完成后执行。如果您正在读取一个大的表,并且/或者有频繁的读和写操作,这可能意味着大量的查询积压。

当对InnoDB表执行查询时,只有涉及的行被锁定,表的其余部分仍可用于CRUD操作。这意味着查询可以在同一个表上同时运行,前提是它们不使用同一行。

这个特性在InnoDB中被称为并发。尽管并发性很好,但对于选择的表范围有一个主要缺点,即在内核线程之间切换时会产生开销,您应该对内核线程设置一个限制,以防止服务器停止。

事务和回滚

当你在MyISAM中运行一个操作时,更改被设置;在InnoDB中,这些更改可以回滚。用于控制事务的最常用命令是COMMIT、ROLLBACK和SAVEPOINT。1. COMMIT -你可以写多个DML操作,但是只有在COMMIT时更改才会被保存。ROLLBACK -你可以放弃任何尚未提交的操作。SAVEPOINT—设置ROLLBACK操作可以回滚到的操作列表中的一个点

可靠性

MyISAM不提供数据完整性——硬件故障、不干净的关机和取消的操作都可能导致数据损坏。这将需要完全修复或重新构建索引和表。

另一方面,InnoDB使用事务日志、双写缓冲区和自动校验和验证来防止损坏。在InnoDB做任何更改之前,它会将事务之前的数据记录到一个名为ibdata1的系统表空间文件中。如果出现崩溃,InnoDB会通过重放这些日志自动恢复。

全文索引

InnoDB直到MySQL 5.6.4版本才支持FULLTEXT索引。在撰写本文时,许多共享主机提供商的MySQL版本仍然低于5.6.4,这意味着InnoDB表不支持FULLTEXT索引。

然而,这并不是使用MyISAM的正当理由。最好换一个支持最新版本MySQL的主机提供商。并不是说使用FULLTEXT索引的MyISAM表不能转换为InnoDB表。

结论

总之,InnoDB应该是您的默认存储引擎选择。在满足特定需求时选择MyISAM或其他数据类型。

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

我在表格中简要地讨论了这个问题,这样你就可以决定是使用InnoDB还是MyISAM。

下面是在哪种情况下应该使用哪种db存储引擎的一个小概述:

                                                 MyISAM   InnoDB
----------------------------------------------------------------
Required full-text search                        Yes      5.6.4
----------------------------------------------------------------
Require transactions                                      Yes
----------------------------------------------------------------
Frequent select queries                          Yes      
----------------------------------------------------------------
Frequent insert, update, delete                           Yes
----------------------------------------------------------------
Row locking (multi processing on single table)            Yes
----------------------------------------------------------------
Relational base design                                    Yes

总结

在几乎所有的情况下,InnoDB都是最好的选择 但是,经常阅读,几乎不写,使用MyISAM 全文搜索MySQL <= 5.5,使用MyISAM