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

来源:这里教程网 时间:2026-02-28 12:53:18 作者:

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

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

作为

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教程

相关推荐