InnoDB和MyISAM存储引擎的区别汇总

1、MyISAM不支持事务,InnoDB是事务类型的存储引擎,当我们的表需要用到事务支持的时候,那肯定是不能选择MyISAM了。

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

   	表级锁:直接锁定整张表,在锁定期间,其他进程无法对该表进行写操作,如果设置的是写锁,那么其他进程读也不允许
   	MyISAM是表级锁定的存储引擎,它不会出现死锁问题
   	 
   	对于write,表锁定原理如下:
   	 
   	如果表上没有锁,在其上面放置一个写锁,否则,把锁定请求放在写锁队列中。
   	 
   	对于read,表锁定原理如下 :
   	 
   	如果表上没有写锁定,那么把一个读锁放在其上面,否则把锁请求放在读锁定队列中
   	 
   	当一个锁定被释放时,表可被写锁定队列中的线程得到,然后才是读锁定队列中的线程。这意味着,如果你在一个表上有许多更新,那么你的SELECT语句将等到所有的写锁定线程执行完。
   	
   	行级锁:只对指定的行进行锁定,其他进程还是可以对表中的其他行进行操作的。
   	 
   	行级锁是Mysql粒度最小的一种锁,它能大大的减少数据库操作的冲突,但是粒度越小实现成本也越大。
   	 
   	行级锁可能会导致“死锁”,那到底是怎么导致的呢,分析原因:Mysql行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,那么Mysql就会锁定这个主键索引,如果sql语句操作的是非主键索引,那么Mysql会先锁定这个非主键索引,再去锁定主键索引。
   	 
   	在UPDATEDELETE操作时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不支持(5.6以后支持全文索引)

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

网上截取了前辈们测试结论:

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

引擎类型MyISAMInnoDB性能相差
count0.00083573.01633609
查询主键0.0057080.157427.57
查询非主键24.0180.373.348
更新主键0.0081240.8183100.7
更新非主键0.0041410.026256.338
插入0.0041880.369488.21
  • (1)加了索引以后,对于MyISAM查询可以加快:4 206.09733倍,对InnoDB查询加快510.72921倍,同时对MyISAM更新速度减慢为原来的1/2,InnoDB的更
    新速度减慢为原来的1/30。要看情况决定是否要加索引,比如不查询的log表,不要做任何的索引。
  • (2)如果你的数据量是百万级别的,并且没有任何的事务处理,那么用MyISAM是性能最好的选择。
  • (3)InnoDB表的大小更加的大,用MyISAM可省很多的硬盘空间。

在我们测试的这个38w的表中,表占用空间的情况如下:

引擎类型MyISAMInnoDB
数据53,924 KB58,976 KB
索引13,640 KB21,072 KB
占用总空间67,564 KB80,048 KB

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

引擎类型MyISAMInnoDB
数据56,166 KB90,736 KB
索引67,103 KB88,848 KB
占用总空间123,269 KB179,584 KB
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值