好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

MySQL中InnoDB和MyISAM的存储引擎的差异

MySQL 数据库区别于其他数据库的很重要的一个特点就是其插件式的表存储引擎,其基于表,而不是数据库。由于每个存储引擎都有其特点,因此我们可以针对每一张表来挑选最合适的存储引擎。

作为 DBA ,我们应该深刻的认识存储引擎。今天介绍两种最常见的存储引擎和它们的区别: InnoDB 和 MyISAM 。

InnoDB 存储引擎

InnoDB 存储引擎支持事务,其设计目标主要就是面向 OLTP(On Line Transaction Processing 在线事务处理) 的应用。特点为行锁设计、支持外键,并支持非锁定读。从 5.5.8 版本开始, InnoDB 成为了 MySQL 的默认存储引擎。

InnoDB 存储引擎采用聚集索引(clustered)的方式来存储数据,因此每个表都是按照主键的顺序进行存放,如果没有指定主键, InnoDB 会为每行自动生成一个 6 字节的 ROWID 作为主键。

MyISAM 存储引擎

MyISAM 存储引擎不支持事务、表锁设计,支持全文索引,主要面向 OLAP(On Line Analytical Processing 联机分析处理) 应用,适用于数据仓库等查询频繁的场景。在 5.5.8 版本之前, MyISAM 是 MySQL 的默认存储引擎。该引擎代表着对海量数据进行查询和分析的需求。它强调性能,因此在查询的执行速度比 InnoDB 更快。

InnoDB 和 MyISAM 的区别

事务

为了数据库操作的原子性,我们需要事务。保证一组操作要么都成功,要么都失败,比如转账的功能。我们通常将多条 SQL 语句放在 begin 和 commit 之间,组成一个事务。

InnoDB 支持, MyISAM 不支持。

主键

由于 InnoDB 的聚集索引,其如果没有指定主键,就会自动生成主键。
MyISAM 支持没有主键的表存在。

外键

为了解决复杂逻辑的依赖,我们需要外键。比如高考成绩的录入,必须归属于某位同学,我们就需要高考成绩数据库里有准考证号的外键。

InnoDB 支持, MyISAM 不支持。

索引

为了优化查询的速度,进行排序和匹配查找,我们需要索引。比如所有人的姓名从 a-z 首字母进行顺序存储,当我们查找 zhangsan 或者第 44 位的时候就可以很快的定位到我们想要的位置进行查找。

InnoDB 是聚集索引,数据和主键的聚集索引绑定在一起,通过主键索引效率很高。如果通过其他列的辅助索引来进行查找,需要先查找到聚集索引,再查询到所有数据,需要两次查询。

MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据的指针。

从 InnoDB 1.2.x 版本, MySQL5.6 版本后,两者都支持全文索引。

auto_increment 自增

对于自增数的字段, InnoDB 要求该列必须是索引,同时必须是索引的第一个列,否则会报错:

mysql> create table test(
    -> a int auto_increment,
    -> b int,
    -> key(b,a)
    -> ) engine=InnoDB;
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

把 (b,a) 顺序替换为 (a,b) 即可。

而 MyISAM 可以将该字段与其他字段随意顺序组成成联合索引。

表行数

很常见的需求是看表中有多少条数据,此时我们需要 select count(*) from table_name 。

InnoDB 不保存表行数,需要进行全表扫描。 MyISAM 用一个变量保存,直接读取该值,更快。当时当带有 where 查询的时候,两者一样。

存储

数据库的文件都是需要在磁盘中进行存储,当应用需要时再读取到内存中。一般包含数据文件、索引文件。

InnoDB 分为:

.frm 表结构文件 .ibdata1 共享表空间 .ibd 表独占空间 .redo 日志文件

MyISAM 分为三个文件:

.frm 存储表定义 .MYD 存储表数据 .MYI 存储表索引

执行速度

如果你的操作是大量的查询操作,如 SELECT ,使用 MyISAM 性能会更好。
如果大部分是删除和更改的操作,使用 InnoDB 。

InnoDB 和 MyISAM 的索引都是 B+ 树索引,通过索引可以查询到数据的主键,不熟悉 B+ 树的可以查看MySQL InnoDB索引原理和算法。两者的性能区别主要在于查询到数据主键后两者的处理方式却不同。

InnoDB 会缓存索引和数据文件,一般以 16KB 为一个最小单元(数据页大小)和磁盘进行交互, InnoDB 在查询到索引数据后实际得到的是主键的 ID ,它需要在内存中的数据页中查找该行的全部数据,但如果该数据不是加载过的热数据,还需要进行数据页的查找和替换,这其中可能牵涉到多次 I/O 操作和内存中数据查找,导致耗时较高。

而 MyISAM 存储引擎只缓存索引文件,不缓存数据文件,其数据文件的缓存直接使用操作系统的缓存,这点非常独特。此时相同的空间能够加载更多的索引,因此当缓存空间有限时, MyISAM 的索引数据页替换次数会更少。根据前面我们知道 MyISAM 的文件分为 MYI 和 MYD ,当我们通过 MYI 查找到主键 ID 时,其实得到是 MYD 数据文件的 offset 偏移量,查找数据比 InnoDB 寻址映射要快的多。

但由于 MyISAM 是表锁,而 InnoDB 支持行锁,因此在牵涉到大量写操作时, InnoDB 的并发性能比 MyISAM 好很多。同时 InnoDB 还通过 MVVC 多版本控制来提高并发读写性能。

delete 删除数据

调用 delete from table 时, MyISAM 会直接重建表, InnoDB 会一行一行的删除,但是可以用 truncate table 代替。参考: mysql清空表数据的两种方式和区别。

MyISAM 仅支持表锁,每次操作锁定整张表。
InnoDB 支持行锁,每次操作锁住最小数量的行数据。

表锁相比于行锁消耗的资源更少,且不会出现死锁,但同时并发性能差。行锁消耗更多的资源,速度较慢,且可能发生死锁,但是因为锁定的粒度小、数据少,并发性能好。如果 InnoDB 的一条语句无法确定要扫描的范围,也会锁定整张表。

当行锁发生死锁的时候,会计算每个事务影响的行数,然后回滚行数较少的事务。

数据恢复

MyISAM 崩溃后无法快速的安全恢复。 InnoDB 有一套完善的恢复机制。

数据缓存

MyISAM 仅缓存索引数据,通过索引查询数据。 InnoDB 不仅缓存索引数据,同时缓存数据信息,将数据按页读取到缓存池,按 LRU(Latest Rare Use 最近最少使用) 算法来进行更新。

如何选择存储引擎

创建表的语句都是相同的,只有最后的 type 来指定存储引擎。

MyISAM

1、大量查询总 count

2、查询频繁,插入不频繁

3、没有事务操作

InnoDB

1、需要高可用性,或者需要事务

2、表更新频繁

推荐学习:MySQL教程

以上就是MySQL中InnoDB和MyISAM的存储引擎的差异的详细内容,更多请关注Gxlcms其它相关文章!

查看更多关于MySQL中InnoDB和MyISAM的存储引擎的差异的详细内容...

  阅读:34次