InnoDB和 MyISAM的区别

 MyISAM 和InnoDB

情景一:

在写多读少的情况下选择哪一个?

      InnoDB。它的插入性能比较好,对于并发事务的处理较好。

分析总结所适用场景:

  • 需要事务支持(具有较好的事务特性)
  • 行级锁定对高并发有很好的适应能力,但需要确保查询是通过索引完成
  • 数据更新较为频繁的场景
  • 数据一致性要求较高
  • 硬件设备内存较大,可以利用InnoDB较好的缓存能力来提高内存利用率,尽可能减少磁盘 IO
  1. 主键尽可能小,避免给Secondary index带来过大的空间负担
  2. 避免全表扫描,因为会使用表锁
  3. 尽可能缓存所有的索引和数据,提高响应速度
  4. 在大批量小插入的时候,尽量自己控制事务而不要使用autocommit自动提交
  5. 合理设置innodb_flush_log_at_trx_commit参数值,不要过度追求安全性
  6. 避免主键更新,因为这会带来大量的数据移动

情景二:

如果对读取速度要求比较高如何选?

      MyISM。

分析总结所使用场景:

  • 不需要事务支持(不支持)
  • 并发相对较低(锁定机制问题)
  • 数据修改相对较少(阻塞问题),以读为主
  • 数据一致性要求不是非常高
  1. 尽量索引(缓存机制)
  2. 调整读写优先级,根据实际需求确保重要操作更优先
  3. 启用延迟插入改善大批量写入性能
  4. 尽量顺序操作让insert数据都写入到尾部,减少阻塞
  5. 分解大的操作,降低单个操作的阻塞时间
  6. 降低并发数,某些高并发场景通过应用来进行排队机制
  7. 对于相对静态的数据,充分利用Query Cache可以极大的提高访问效率
  8. MyISAM的Count只有在全表扫描的时候特别高效,带有其他条件的count都需要进行实际的数据访问

 下面给出了详细的分析:

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高
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值