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

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

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


当前回答

我在表格中简要地讨论了这个问题,这样你就可以决定是使用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

其他回答

有点晚了…但这是我几个月前写的一篇相当全面的文章,详细介绍了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或其他数据类型。

如果它是70%的插入和30%的读取,那么它更像是在InnoDB端。

根据我的经验,MyISAM是一个更好的选择,只要你不做delete、update、大量的单个INSERT、事务和全文索引。顺便说一句,CHECK TABLE太可怕了。随着表的行数越来越老,你不知道它什么时候会结束。

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

我不是数据库专家,也不是凭经验说的。然而:

MyISAM表使用表级锁定。根据您的流量估计,您每秒有接近200个写入操作。有了MyISAM,在任何时候只有其中一项可以进行。您必须确保您的硬件能够跟上这些事务,以避免超时,即单个查询的时间不能超过5毫秒。

这就意味着你需要一个支持行级锁的存储引擎,比如InnoDB。

另一方面,编写几个简单的脚本来模拟每个存储引擎的负载,然后比较结果应该是相当简单的。