InnoDB和MyISAM之间的主要区别是什么?

评论

如果需要数据库引擎,请使用InnoDB。您无法将两者进行比较。

尽管以下许多答案是正确的,但恕我直言,它们并不能将事情归结为清楚。这个站点可以,要点是:InnoDB是行级锁定,MyISAM是表级锁定。通常,这意味着MyISAM对于OLAP(分析,主要是读取)会更好,而InnoDB对于OLTP(事务,主要是写入,或至少很多写入)会更好。

#1 楼

我看到的第一个主要区别是InnoDB实现行级锁定,而MyISAM只能执行表级锁。您会在InnoDB中发现更好的崩溃恢复。但是,直到v5.6为止,它都没有FULLTEXT搜索索引,MyISAM也没有。 InnoDB还实现了事务,外键和关系约束,而MyISAM则没有。

列表可以更进一步。但是,它们在彼此的有利与不利方面都有其独特的优势。因此,在某些情况下,每种方法都比其他方法更合适。

所以总结一下(TL; DR):只能执行完整的表级锁定。
InnoDB具有更好的崩溃恢复。
MyISAM具有FULLTEXT搜索索引,InnoDB直到MySQL 5.6(2013年2月)才提供。
InnoDB实现事务,外键和关系约束,而MyISAM没有。


评论


亲爱的先生,那么最终该用什么呢? MyISAM还是InnoDB?完全感到困惑...我的网站正在使用mysql,我需要决定。

–sqlchild
2012年8月30日在11:44

根据应用程序,写下具有所需功能的列表(例如,全文搜索,外键...),然后尝试确定一项(尝试对每个功能进行评分,然后计算分数)。您将无法全部拥有它们,但是由您决定最需要巫婆功能。

– poelinca
2012年8月30日12:14

我编辑了他的帖子以进行澄清。

– Mathias Lykkegaard Lorenzen
13年7月23日在6:24

@MathiasLykkegaardLorenzen谢谢,这是我们喜欢stackexchange的原因之一

– poelinca
13年7月25日在23:37

从5.6.4版开始,InnoDB支持FULLTEXT搜索。 dev.mysql.com/doc/refman/5.6/en/fulltext-restrictions.html

–白日梦
2014年11月2日,下午4:34

#2 楼

尚未提及的另一个主要区别是如何完成每个存储引擎的缓存。
MYISAM
使用的主要机制是密钥缓存。它仅从.MYI文件缓存索引页。要确定密钥缓存的大小,请运行以下查询:
SELECT CONCAT(ROUND(KBS/POWER(1024,
IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.4999),
SUBSTR(' KMG',IF(PowerOf1024<0,0,
IF(PowerOf1024>3,0,PowerOf1024))+1,1))
recommended_key_buffer_size FROM
(SELECT LEAST(POWER(2,32),KBS1) KBS
FROM (SELECT SUM(index_length) KBS1
FROM information_schema.tables
WHERE engine='MyISAM' AND
table_schema NOT IN ('information_schema','mysql')) AA ) A,
(SELECT 2 PowerOf1024) B;

,根据给定的当前数据集,这将给出MyISAM密钥缓存的推荐设置(key_buffer_size)(查询会将建议的上限限制为4G(4096M)) 。对于32位操作系统,限制为4GB;对于64位,限制为8GB。调整InnoDB缓冲池的大小,运行以下查询:
SELECT CONCAT(ROUND(KBS/POWER(1024,
IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.49999),
SUBSTR(' KMG',IF(PowerOf1024<0,0,
IF(PowerOf1024>3,0,PowerOf1024))+1,1)) recommended_innodb_buffer_pool_size
FROM (SELECT SUM(data_length+index_length) KBS FROM information_schema.tables
WHERE engine='InnoDB') A,
(SELECT 2 PowerOf1024) B;

给定当前数据集,这将为InnoDB缓冲池的大小(innodb_buffer_pool_size)提供建议设置。
不要忘记调整InnoDB日志文件的大小(ib_logfile0和ib_logfile1),MySQL源代码将所有InnoDB日志文件的合并大小的上限限制为<4G(4096M)。为了简单起见,仅给出两个日志文件,这里是如何调整它们的大小:

步骤1)将innodb_log_file_size = NNN添加到/etc/my.cnf
(NNN应该是innodb_buffer_pool_的25%大小或2047M,以较小者为准)
步骤2)service mysql stop

步骤3)rm /var/log/mysql/ib_logfile[01]

步骤4)service mysql start(重新创建ib_logfile0和ib_logfile1)

CAVEAT
两个查询的末尾是一个内联查询
(SELECT 2 PowerOf1024) B


(SELECT 0 PowerOf1024)以字节为单位给出设置

(SELECT 1 PowerOf1024)以千字节为单位设置

(SELECT 2 PowerOf1024)以千兆字节为单位给出设置

(SELECT 3 PowerOf1024)以千兆字节为单位给出设置
功率不小于0或大于3被接受

EPILOGUE
是常识。如果内存有限,混合使用存储引擎或其组合,则必须针对不同的情况进行调整。

如果您有2GB RAM和16GB InnoDB,请分配512M作为innodb_buffer_pool。
如果您有2GB RAM和4GB MyISAM索引,请分配512M作为key_buffer_size。 16GB InnoDB,将512M分配为key_buffer_size,将512M分配给innodb_buffer_pool_size。

可能的情况是无止境的!!
请记住,无论您分配什么,都要为DB Connections和操作系统留出足够的RAM。 br />

评论


那些是坏公式!

–里克·詹姆斯(Rick James)
2011年6月23日下午0:06

(糟糕-别忘了不要有段落)...我将添加一个“答案”。

–里克·詹姆斯(Rick James)
2011年6月23日下午0:07

Rolando的缓存大小公式不切实际。 -不需要2的幂。 -在32位操作系统上不可能有4GB。-这是我将它们设置为以下内容的摘要:mysql.rjweb.org/doc.php/memory(它解决了影响内存使用的其他各种设置。)

–里克·詹姆斯(Rick James)
2011年6月23日下午0:13

@Rick:2的幂是用来以不同单位显示答案。做(SELECT 2 PowerOfTwo)设置答案的显示,以MB为单位。执行(SELECT 3 PowerOfTwo)设置以GB为单位的显示。 (SELECT 1 PowerOfTwo)以KB显示。 (SELECT 0 PowerOfTwo)以字节为单位显示。这就是(SELECT 2 PowerOfTwo)所做的。因此,仅需显示,而不在体系结构中强加任何假定值。

– RolandoMySQLDBA
2011年6月23日在2:25



@Rick:你知道吗?实际上,出于两个非常重要的原因,我将给您+1。 1)您的URL确认我的答案是正确的,因为4GB是分配给key_buffer_size的最大数字。 2)您的答案以及您的URL对于内存非常低的计算机来说很有意义。我会在应得的信用额上给予信用。

– RolandoMySQLDBA
2011年6月23日在2:41



#3 楼

InnoDB提供:


ACID事务
行级锁定
外键约束
自动崩溃恢复
表压缩(读/写)
空间数据类型(无空间索引)

在InnoDB中,除了TEXT和BLOB之外,一行中的所有数据最多可以占用8,000个字节。在MySQL 5.6(2013年2月)之前,InnoDB中不提供全文索引。在InnoDB中,COUNT(*) s(未使用WHEREGROUP BYJOIN时)的执行速度比MyISAM慢,因为行计数没有内部存储。 InnoDB将数据和索引都存储在一个文件中。 InnoDB使用缓冲池来缓存数据和索引。

MyISAM提供:快速COUNT(*) s(不使用WHEREGROUP BYJOIN时)
全文索引(更新:从MySQL 5.6开始在InnoDB中受支持)
磁盘占用量较小
表压缩率很高(只读)
空间数据类型和索引(R树) (更新:从MySQL 5.7开始在InnoDB中受支持)

MyISAM具有表级锁定,但没有行级锁定。没有交易。没有自动崩溃恢复,但是它确实提供了修复表功能。没有外键约束。与InnoDB表相比,MyISAM表在磁盘上的大小通常更紧凑。如果需要,可以通过使用myisampack进行压缩来进一步高度减小MyISAM表的大小,但该表将变为只读状态。 MyISAM将索引存储在一个文件中,将数据存储在另一个文件中。 MyISAM使用键缓冲区来缓存索引,而将数据缓存管理留给操作系统。

总体上,我建议将InnoDB用于大多数用途,将MyISAM仅用于特殊用途。现在,InnoDB是新MySQL版本中的默认引擎。

评论


我阅读了您的答案,并将其与此处已有的其他人进行了比较。您是唯一提及BLOB的人。他们通常被认为是理所当然的。您也是唯一提及myisampack的人,myisampack是快速读取MyISAM表的无名英雄之一。您的今天是+1 !!!

– RolandoMySQLDBA
2011年8月23日,下午3:45

示例是压缩的只读表,在其中您可以通过完全替换表来对其进行不频繁更新。

–dabest1
19年1月1日,0:21

#4 楼

游戏有点晚了……但是这是我几个月前写的一篇非常全面的文章,详细介绍了MYISAM和InnoDB之间的主要区别。抢一杯(可能还有饼干),然后享用。


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

引用完整性

引用完整性可确保表之间的关系保持一致。更具体地说,这意味着当一个表(例如清单)具有指向另一个表(例如产品)的外键(例如产品ID)时,当指向该表的更新或删除发生时,这些更改将级联到链接中表。在我们的示例中,如果产品被重命名,则链接表的外键也会更新;如果从“产品”表中删除了产品,则指向已删除条目的所有列表也会被删除。此外,任何新列表都必须具有指向有效的现有条目的外键。

InnoDB是关系DBMS(RDBMS),因此具有参照完整性,而MyISAM则没有。
<事务和原子性

表中的数据使用数据操作语言(DML)语句(例如SELECT,INSERT,UPDATE和DELETE)进行管理。一个事务将两个或多个DML语句组合在一起,成为一个工作单元,因此将应用整个单元,或者不应用整个单元。

MyISAM不支持事务,而InnoDB则支持。 >
如果在使用MyISAM表时某个操作被中断,则该操作将立即中止,即使该操作未完成,受影响的行(甚至每一行中的数据)仍会受到影响。 br />
如果使用InnoDB表时操作被中断,因为它使用具有原子性的事务,则任何未完成的事务都不会生效,因为没有进行提交。

表锁定vs行锁定

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

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

InnoDB中的此功能称为并发。就并发性而言,最大的缺点是它适用于选定的表范围,因为在内核线程之间进行切换会产生开销,并且应该对内核线程设置一个限制,以防止服务器停机。

事务和回滚

在MyISAM中运行操作时,更改已设置;在InnoDB中,这些更改可以回滚。用于控制事务的最常见命令是COMMIT,ROLLBACK和SAVEPOINT。 1. COMMIT-您可以编写多个DML操作,但所做的更改仅在进行COMMIT时保存。2. ROLLBACK-您可以放弃尚未提交的所有操作3. SAVEPOINT-在以下列表中设置一个点ROLLBACK操作可以回滚到的操作

可靠性

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

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

FULLTEXT Indexing

InnoDB在MySQL 5.6.4版之前不支持FULLTEXT索引。截至撰写本文时,许多共享的托管服务提供商的MySQL版本仍低于5.6.4,这意味着InnoDB表不支持FULLTEXT索引。使用MyISAM。最好改用支持MySQL最新版本的托管服务提供商。并不是说使用FULLTEXT索引的MyISAM表不能转换为InnoDB表。

结论

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

评论


谢谢,非常有益和清晰的摘要。

–informatik01
19年4月26日在10:21

#5 楼

还有一件事:您只需拍摄文件系统快照即可备份InnoDB表。备份MyISAM需要使用mysqldump并且不能保证是一致的(例如,如果您插入父表和子表,则可能仅在备份中找到子表的行)。

基本上,如果您有数据的另一个副本,并且仅将其缓存在MySQL中,例如为了允许从PHP网站访问它的标准方法,那么MyISAM很好(即,它比平面CSV文件或用于查询和并发访问的日志文件要好)。如果数据库是数据的实际“主副本”,并且您正在使用来自用户的真实数据来执行INSERTUPDATE,那么使用InnoDB以外的任何其他方式都是愚蠢的,MyISAM是不可靠且难以管理的,您将有一半的时间在执行myisamchk,而没有任何性能提升...

(我的个人经验:MyISAM中有2 TB的DB)。

#6 楼

以我的经验,最大的不同是每个引擎处理锁定的方式。 InnoDB使用行锁定,而MyISAM使用表锁定。根据经验,我使用InnoDB编写重表,使用MyISAM编写重表。

其他重要区别包括:


InnoDB支持事务和外键。 MyISAM不会。
MyISAM使用全文索引。
MyISAM在执行数据完整性方面做得很差。


评论


过时了-InnoDB现在具有FULLTEXT和SPATIAL。 InnoDB对于读取和写入繁重的负载都很有用。

–里克·詹姆斯(Rick James)
18-10-28在18:31

#7 楼

我倾向于将MyISAM视为MySQL的“默认”表选择,因此我将指出大多数InnoDB用户的区别


行级别锁定
外键执法
交易支持
高性能系统的性能受到打击


评论


除了最新的MySQL版本不再使用MyISAM作为默认引擎。在5.5中,他们将默认值更改为InnoDB :)。我不同意InnoDB通常只会受到“性能冲击”的说法。设计良好的InnoDB表具有正确的索引和配置好的内存设置,可以使InnoDB表的性能与MyISAM中的相同架构相同

– TechieGurl
2011年6月24日13:44



在许多“高使用率”情况下,InnoDB实际上比MyISAM表现更好。 MyISAM是针对特定问题的特定工具,而InnoDB在大多数情况下都可以为您提供更好的服务(因此,MySQL团队将其设置为默认引擎)。这是因为MyISAM是很长一段时间以来唯一的引擎,即使InnoDB成熟,MySQL社区也逐渐习惯于默认使用MyISAM。

–尼克·查马斯(Nick Chammas)
2011年8月15日在19:53



在MySQL 5.6开发周期的中途添加了对InnoDB的FULLTEXT搜索。现在引用的URL也涵盖了InnoDB。

– Max Webster
2012-12-20 6:52



#8 楼

MYISAM

MYISAM提供表级锁定,全文本搜索。
MYISAM具有处理所有存储引擎的最灵活的AUTO_INCREMENTED列。
MYISAM不支持事务。

INNODB

INNODB是事务安全存储引擎。
INNODB具有提交,回滚和崩溃恢复功能。
INNODB支持外键引用完整性。

#9 楼

包括MySQL 5.6更改

INNODB存储引擎:


它提供完整的ACID(原子性,一致性,隔离性,耐用性)
兼容性。多版本用于将事务与另一个事务隔离。
在MySQL服务器或运行该服务器的主机崩溃后,InnoDB提供自动恢复。
InnoDB支持外键和参照完整性,包括级联的删除和更新。
MySQL 5.6构建在完全集成为默认存储引擎的InnoDB平台上。

持久性优化器统计信息:提高了InnoDB索引统计信息的准确性和一致性跨MySQL重新启动。

修剪InnoDB表缓存:为了减轻具有大量表的系统上的内存负载,InnoDB现在释放与打开的表关联的内存。 LRU算法选择最长的表而不被访问。

支持全文搜索:一种特殊的索引FULLTEXT索引可帮助InnoDB处理涉及基于文本的查询和DML操作列及其包含的单词。这些索引在物理上表示为整个InnoDB表。
InnoDB在全文搜索上似乎比MyISAM快得多

因此,如果您已经升级到5.6,则使用MyISAM Engine毫无意义,否则请不要等待用于升级到MySQL 5.6。

使用MySQL 5.6的InnoDB VS MyISAM性能

#10 楼

MyISAM
MyISAM是MySQL的存储引擎。在MySQL 5.5之前,它是MySQL的默认存储引擎。它基于较早的ISAM存储引擎。
MyISAM针对具有大量读取操作,很少写入或根本不写入的环境进行了优化。 MyISAM允许快速读取的原因是其索引的结构:每个条目都指向数据文件中的一条记录,并且指针从文件的开头偏移。这样,可以快速读取记录,尤其是在格式为FIXED的情况下。因此,这些行具有恒定的长度。数据仓库是一个可能首选MyISAM的典型领域,因为它涉及对非常大的表的查询,并且在不使用数据库时(通常在晚上)进行此类表的更新。插入也很容易,因为新行会附加到数据文件的末尾。但是,删除和更新操作存在更多问题:删除操作必须留一个空白,否则行的偏移量会发生变化;随着行的长度变短,更新也是如此;如果更新使行变长,则该行会碎片化。要对行进行碎片整理并声明可用空间,必须执行OPTIMIZE TABLE命令。由于这种简单的机制,通常MyISAM索引统计信息非常准确。 MyISAM的其他主要缺点是缺少事务支持和外键。
InnoDB
InnoDB是MySQL的存储引擎。 MySQL 5.5及更高版本默认使用它。它提供符合ACID标准的事务功能,并提供外键支持(声明性引用完整性)。
它遵循OpenGIS标准实现SQL和XA事务,表空间,FULLTEXT索引和空间操作。
它是MySQL AB分发的大多数二进制文件中的标准配置,但某些OEM版本除外。该软件已获得Oracle Corporation的双重许可;它是根据GNU通用公共许可证发行的,但也可以授权给希望将InnoDB与专有软件结合的各方。
Forks
MariaDB有一个称为Aria的存储引擎,被称为“崩溃-安全替代MyISAM”。默认情况下,MariaDB和Percona Server使用名为XtraDB的InnoDB分支。 XtraDB由Percona维护。 Oracle InnoDB的更改会定期导入XtraDB,并添加了一些错误修复和额外的功能。