Mysql INNODB 和 MYISAM 选择

本文详细比较了MySQL中MyISAM与InnoDB存储引擎的特点及适用场景,包括事务支持、锁机制、外键支持等方面。

摘录自:http://www.2cto.com/database/201404/291438.html 红客联盟


1、MyISAM不支持事务,InnoDB是事务类型的存储引擎

当我们的表需要用到事务支持的时候,那肯定是不能选择MyISAM了。

2、MyISAM只支持表级锁,BDB支持页级锁和表级锁默认为页级锁,而InnoDB支持行级锁和表级锁默认为行级锁

表级锁:直接锁定整张表,在锁定期间,其他进程无法对该表进行写操作,如果设置的是写锁,那么其他进程读也不允许

MyISAM是表级锁定的存储引擎,它不会出现死锁问题

对于write,表锁定原理如下:

如果表上没有锁,在其上面放置一个写锁,否则,把锁定请求放在写锁队列中。

对于read,表锁定原理如下 :

如果表上没有写锁定,那么把一个读锁放在其上面,否则把锁请求放在读锁定队列中

当一个锁定被释放时,表可被写锁定队列中的线程得到,然后才是读锁定队列中的线程。这意味着,如果你在一个表上有许多更新,那么你的SELECT语句将等到所有的写锁定

线程执行完。

行级锁:只对指定的行进行锁定,其他进程还是可以对表中的其他行进行操作的。

行级锁是Mysql粒度最小的一种锁,它能大大的减少数据库操作的冲突,但是粒度越小实现成本也越大。

行级锁可能会导致“死锁”,那到底是怎么导致的呢,分析原因:Mysql行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主

键索引,那么Mysql就会锁定这个主键索引,如果sql语句操作的是非主键索引,那么Mysql会先锁定这个非主键索引,再去锁定主键索引。

在UPDATE 和 DELETE操作时Mysql不仅会锁定所有WHERE 条件扫描过得索引,还会锁定相邻的键值。

“死锁”举例分析:

表Test:(ID,STATE,TIME) 主键索引:ID 非主键索引:STATE

当执行"UPDATE STATE =1011 WHERE STATE=1000" 语句的时候会锁定STATE索引,由于STATE 是非主键索引,所以Mysql还会去请求锁定ID索引

当另一个SQL语句与语句1几乎同时执行时:“UPDATE STATE=1010 WHERE ID=1” 对于语句2 Mysql会先锁定ID索引,由于语句2操作了STATE字段,所以Mysql还会请求锁

定STATE索引。这时。彼此锁定着对方需要的索引,又都在等待对方释放锁定。所以出现了"死锁"的情况。

行级锁的优点:

有许多线程访问不同的行时,只存在少量的冲突。

回滚时只有少量的更改

可以长时间锁定单一的行

行级锁缺点:

相对于页级锁和表级锁来说占用了更多的内存

当表的大部分行在使用时,比页级锁和表级锁慢,因为你必须获得更多的锁

当在大部分数据上经常使用GROUP BY操作,肯定会比表级锁和页级锁慢。

页级锁:表级锁速度快,但是冲突多;行级锁速度慢,但冲突少;页级锁就是他俩折中的,一次锁定相邻的一组记录。

3、MyISAM引擎不支持外键,InnoDB支持外键

4、MyISAM引擎的表在大量高并发的读写下会经常出现表损坏的情况

我们正在做的项目就遇到这个问题,表的INSERT 和 UPDATE操作很频繁,原来用的MyISAM引擎,导致表隔三差五就损坏,后来更换成了InnoDB引擎。

其他容易导致表损坏原因:

服务器突然断电导致数据文件损坏,强制关机(mysqld未关闭情况下)导致表损坏

mysqld进程在写入操作的时候被杀掉

磁盘故障

表损坏常见症状:

查询表不能返回数据或返回部分数据

打开表失败: Can’t open file: ‘×××.MYI’ (errno: 145) 。

Error: Table 'p' is marked as crashed and should be repaired 。

 

Incorrect key file for table: '...'. Try to repair it

Mysql表的恢复:

对于MyISAM表的恢复:

可以使用Mysql自带的myisamchk工具: myisamchk -r tablename 或者 myisamchk -o tablename(比前面的更保险) 对表进行修复

5、对于count()查询来说MyISAM更有优势
因为MyISAM存储了表中的行数记录,执行SELECT COUNT() 的时候可以直接获取到结果,而InnoDB需要扫描全部数据后得到结果。
但是注意一点:对于带有WHERE 条件的 SELECT COUNT()语句两种引擎的表执行过程是一样的,都需要扫描全部数据后得到结果

6、 InnoDB是为处理巨大数据量时的最大性能设计,它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。

7、MyISAM支持全文索引(FULLTEXT),InnoDB不支持

8、MyISAM引擎的表的查询、更新、插入的效率要比InnoDB高

我没有做过详细的测试,就在网上截取了前辈们测试结论:

所有的性能测试在:Micrisoft window xp sp2 , Intel(R) Pentinum(R) M processor 1.6oGHz 1G 内存的电脑上测试。

测试方法:连续提交10个query, 表记录总数:38万 , 时间单位 s

引擎类型 MyISAM InnoDB 性能相差

count 0.0008357 3.0163 3609

查询主键 0.005708 0.1574 27.57

查询非主键 24.01 80.37 3.348

更新主键 0.008124 0.8183 100.7

更新非主键 0.004141 0.02625 6.338

插入 0.004188 0.3694 88.21

(1)加了索引以后,对于MyISAM查询可以加快:4 206.09733倍,对InnoDB查询加快510.72921倍,同时对MyISAM更新速度减慢为原来的1/2,InnoDB的更 新速度减慢为原来的1/30。要看情况决定是否要加索引,比如不查询的log表,不要做任何的索引。

(2)如果你的数据量是百万级别的,并且没有任何的事务处理,那么用MyISAM是性能最好的选择。

(3)InnoDB表的大小更加的大,用MyISAM可省很多的硬盘空间。

在我们测试的这个38w的表中,表占用空间的情况如下:
引擎类型 MyISAM InnoDB
数据 53,924 KB 58,976 KB
索引 13,640 KB 21,072 KB
占用总空间 67,564 KB 80,048 KB

另外一个176W万记录的表, 表占用空间的情况如下:

引擎类型 MyIsam InnorDB
数据 56,166 KB 90,736 KB
索引 67,103 KB 88,848 KB
占用总空间 123,269 KB 179,584 KB

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值