MySQL中InnoDB和MyISAM引擎的对比
目录
- 索引对比
- 锁对比
- 事务对比
- 并发
- 全文索引对比
- 外键
- 其他
一.索引对比
1.b+树概念
我们这里关注b+树的两个特性:
- 叶子节点包含数据data(data并不特指数据库中的某一行数据,也可以是某个数值,指针等)
- 叶子节点均在同一层,且每个节点均可以直接找到上一个或者下一个节点(双向指针,比常规的b+树多了一个指向上一个的指针)
2.innodb
以用户表为例,id
为主键,另外name存在索引idx_name
:
create table `t_user` ( `id` bigint, `name` varchar(10), `age` int, primary key (`id`), key `idx_name` (`name`) );
插入数据:
insert into t_user (id,`name`,age) values (1,'n7',10), (2,'n6',20), (3,'n5',30), (4,'n4',40), (5,'n3',50), (6,'n2',60), (7,'n1',70)
①聚簇索引(聚集索引)
聚簇索引:行数据与键值(主键)紧凑地存储在一起;
innodb中表现为:b+树叶子节点的data用于存放行数据(包含主键值、其他列数据、回滚指针、事务id等),物理上索引数据与行数据都放在同一个文件中(.ibd
)
如果没有定义主键,innodb会选择一个非空的唯一索引代替。如果没有这样的索引,innodb会隐式定义一个主键(db_row_id)来作为聚簇索引。
②辅助索引
与聚簇索引最大的不同是:b+树的data存放的并不是行数据,而是主键值;
当select * from t_user where name='n1'
时,会先通过idx_name
索引找到n1
对应的主键的值(id=7),再通过主键值找到行数据 [7,n1,70] 。
3.myisam 索引
与innodb不同,myisam并不使用聚簇索引,myisam的索引数据和行数据是分开的,物理上分别为.myi
索引数据文件和.myd
行数据文件(innodb 索引和行数据均在.idb
文件中)
myisam中,主键索引和其他的一般索引在数据结构上并没有什么区别,b+树的data存放的均是数据行地址。
主键索引:
普通索引:
二.锁对比
mysql支持三种锁定级别,行级、页级、表级;
myisam支持表级锁定,提供与 oracle 类型一致的不加锁读取(non-locking read in selects)
innodb支持行级锁,但值得注意的是innodb的行锁是加到索引上的,所以在某次查找时没有用上索引,innodb表同样会锁全表。
三.事务对比
innodb具有事务,支持4个事务隔离级别,回滚,崩溃修复能力和多版本并发的事务安全,包括acid。如果应用中需要执行大量的insert或update操作,则应该使用innodb,以事务为单位操作可以提高多用户并发操作的性能。
myisam管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的select查询,那么myisam是更好的选择
四.并发
myisam读写互相阻塞:不仅会在写入的时候阻塞读取,myisam还会在读取的时候阻塞写入,但读本身并不会阻塞另外的读。
innodb 读写阻塞与事务隔离级别相关。
五.全文索引
myisam支持fulltext类型的全文索引
innodb不支持fulltext类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好
六.外键
myisam不支持
innodb支持
七.其他
innodb不保存表的具体行数,执行select count(*) from table时需要全表扫描。
myisam用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
站在巨人的肩膀上摘苹果:
推荐阅读
-
MySQL InnoDB 日志管理机制中的MTR和日志刷盘
-
关于Mysql存储引擎中InnoDB与Myisam的主要区别介绍
-
MySQL存储引擎以及MyISAM与InnoDB的区别详解
-
mysql 中InnoDB和MyISAM的区别分析小结
-
MySQL两种表存储结构MyISAM和InnoDB的性能比较测试
-
关于mysql中storage_engine中MYISAM和INNODB的选择
-
Mysql更换MyISAM存储引擎为Innodb的操作记录总结
-
mysql数据库引擎MyISAM与InnoDB之间的区别
-
重新学习Mysql数据库7:详解MyIsam与InnoDB引擎的锁实现
-
MySQL InnoDB 日志管理机制中的MTR和日志刷盘