第十章:第24节 MySQL进阶篇——InnoDB和MyISAM的区别(经典的面试题)

更新于:2018-11-13 13:13:49

MySQL的索引、事务和锁知识到此结束,楠神也是搜集了多方面资料才完成这样的知识体系介绍。对于初学MySQL的朋友来说,是很全面了,应该都是要理解和掌握的。楠神觉着不把MySQL索引、事务和锁弄清了,永远只是一个“糊涂”的没有太高水平的程序员,这是成为大神级别的IT人需掌握得最基础的知识。


这节我们来做个总结,在找工作面试的时候,有一个经典的面试题,那就是“说一说InnoDB和MyISAM的区别?”面试的时候经常会被问到的。


我们前面的章节就是答案,理解透了,有兴致地话足够和面试官“痛聊一晌午”,这样很能显示出自己的水平。


也可能这是个笔试题,我们只能用简短的文字做个概括。



主要区别:


InnoDB是事务安全型的,而MyISAM是非事务安全型的。


InnoDB支持行级锁定,而MyISAM锁的粒度是表级。


MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。


MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。


InnoDB表比MyISAM表更安全,可以在保证数据不会丢失的情况下,切换非事务表到事务表(alter table tablename type=innodb)。


MyISAM管理非事务表,强调的是性能,其执行数度比InnoDB类型更快。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。MyISAM不适合于有大量查询和修改并存的情况,那样查询进程会长时间阻塞。


InnoDB用于事务处理应用程序,具有众多特性,包括事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。


MyISAM着重于性能,InnoDB注重于并发与数据安全。


还有一些细节:


InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。


对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。


通过前面几节内容介绍,大家可以看出来楠神比较着重地讲解InnoDB,其实楠神在开发项目时也是以InnoDB比较多,主要是因为事务比较多。楠神不想给大家造成MyISAM一无是处的感觉,其实MyISAM是很不错的,来自其他地方的摘录:


  作为使用MySQL的用户角度出发,Innodb和MyISAM都是比较喜欢的,如果数据库平台要达到需求:99.9%的稳定性,方便的扩展性和高可用性来说的话,MyISAM绝对是首选。


  原因如下:


  1、平台上承载的大部分项目是读多写少的项目,而MyISAM的读性能是比Innodb强不少的。


  2、MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小。


  3、经常隔1,2个月就会发生应用开发人员不小心update一个表where写的范围不对,导致这个表没法正常用了,这个时候MyISAM的优越性就体现出来了,随便从当天拷贝的压缩包取出对应表的文件,随便放到一个数据库目录下,然后dump成sql再导回到主库,并把对应的binlog补上。如果是Innodb,恐怕不可能有这么快速度,别和我说让Innodb定期用导出xxx.sql机制备份,因为最小的一个数据库实例的数据量基本都是几十G大小。


  4、从接触的应用逻辑来说,select count(*) 和order by 是最频繁的,大概能占了整个sql总语句的60%以上的操作,而这种操作Innodb其实也是会锁表的,很多人以为Innodb是行级锁,那个只是where对它主键是有效,非主键的都会锁全表的。


  5、还有就是经常有很多应用部门需要我给他们定期某些表的数据,MyISAM的话很方便,只要发给他们对应那表的frm.MYD,MYI的文件,让他们自己在对应版本的数据库启动就行,而Innodb就需要导出xxx.sql了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的。


  6、如果和MyISAM比insert写操作的话,Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作,虽然MyISAM可能会逊色Innodb,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分表架构来解决。


  7、如果是用MyISAM的话,merge引擎可以大大加快应用部门的开发速度,他们只要对这个merge表做一些select count(*)操作,非常适合大项目总量约几亿的rows某一类型(如日志,调查统计)的业务表。


  当然Innodb也不是绝对不用,用事务的项目就用Innodb的。另外,可能有人会说你MyISAM无法抗太多写操作,但是可以通过架构来弥补。