InnoDB具有事务,支持4个事务隔离级别,回滚,崩溃修复能力和多版本并发的事务安全,包括ACID。如果应用中需要执行大量的insert和update操作,则应该使用InnoDB,这样可以提高多用户并发操作性能。
InnoDB不支持全文索引,如果一定要用的话,最好使用sphinx等搜索引擎。
MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的select查询,那么MyISAM是更好的选择。
MySQL支持三种锁定级别:行级、页级、表级。
myisam支持表级锁定,提供与Oracle类型一致的不加锁读取。
innodb支持行级锁,innodb表的行锁也不是绝对的,如果在执行一个sql语句时MySQL不能确定要扫描范围,innodb表同样会锁全表,注意间隙锁的影响。
myisam在磁盘上存储成三个文件,第一个文件的名字以表的名字开始,扩展名指出文件类型,frm文件存储表定义,数据文件的扩展名为.MYD,索引文件的扩展名是.MYI。
innodb基于磁盘的资源是Innodb表空间数据文件和它的日志文件,innodb表的大小只受损于操作系统文件的大小。
注意:myisam是保存成文件的形式,在跨平台的数据转移中使用myisam存储会省去不少的麻烦。
innodb使用的聚簇索引、索引就是数据顺序存储,因此能缓存索引,也能缓存数据。
myisam使用的是非聚簇索引、索引和文件分开,随机存储,只能缓存索引。
myisam读写互相阻塞,不仅会在写入的时候阻塞读取,myisa还会在读取的时候阻塞写入,但读本并不会阻塞另外的读。
innodb读写阻塞与事务的隔离级别有关。
MyISAM
1.尽量索引(缓存机制)
2.调整读写优先级,根据实际需求确保重要操作更优先
3.启用延迟插入改善大批量写入性能
4.尽量顺序操作让insert数据都写入到尾部,减少阻塞
5.分解大的操作,降低单个操作的阻塞时间
6.降低并发数,某些高并发场景通过应用来进行排队机制
7.对于相对静态的数据,充分利用Query Cache可以极大的提高访问效率
8.MyISAM的Count只有在全表扫描的时候特别高效,带有其他条件的count都需要进行实际的数据访问
InnoDB
1.主键尽可能小,避免给Secondary index带来过大的空间负担
2.避免全表扫描,因为会使用表锁
3.尽可能缓存所有的索引和数据,提高响应速度
4.在大批量小插入的时候,尽量自己控制事务而不要使用autocommit自动提交
5.合理设置innodb_flush_log_at_trx_commit参数值,不要过度追求安全性
6.避免主键更新,因为这会带来大量的数据移动
1)InnoDB 中不保存表的具体行数,注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的
2)对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引, 如果你为一个表指定AUTO_INCREMENT列,在数据词典里的InnoDB表句柄包含一个名为自动增长计数器的计数器,它被用在为该列赋新值。自动增长计数器仅被存储在主内存中,而不是存在磁盘
3)DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除
4)LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用
5)如果执行大量的SELECT,MyISAM是更好的选择,如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表
InnoDB 在做SELECT的时候,要维护的东西比MYISAM引擎多很多;
1)InnoDB 要缓存数据和索引,MyISAM只缓存索引块,这中间还有换进换出的减少
2)innodb寻址要映射到块,再到行,MyISAM记录的直接是文件的OFFSET,定位比INNODB要快
3)InnoDB 还需要维护MVCC一致;虽然你的场景没有,但他还是需要去检查和维护
MVCC ( Multi-Version Concurrency Control )多版本并发控制
InnoDB :通过为每一行记录添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。但是InnoDB并不存储这些事件发生时的实际时间,相反它只存储这些事件发生时的系统版本号。这是一个随着事务的创建而不断增长的数字。每个事务在事务开始时会记录它自己的系统版本号。每个查询必须去检查每行数据的版本号与事务的版本号是否相同。让我们来看看当隔离级别是REPEATABLE READ时这种策略是如何应用到特定的操作的
1、InnoDB必须找到一个行的版本,它至少要和事务的版本一样老(也即它的版本号不大于事务的版本号)。这保证了不管是事务开始之前,或者事务创建时,或者修改了这行数据的时候,这行数据是存在的。
2、这行数据的删除版本必须是未定义的或者比事务版本要大。这可以保证在事务开始之前这行数据没有被删除。
MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录地址。如图:
这里设表一共有三列,假设我们以Col1为主键,则上图是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:
同样也是一颗B+Tree,data域保存数据记录的地址。因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。
MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。
虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。
第一个重大区别是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。
第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。例如,下图为定义在Col3上的一个辅助索引:
这里以英文字符的ASCII码作为比较准则。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
在数据库开发中,了解不同存储引擎的所有实现方式对于正确使用和优化索引都非常有帮助。
比如:了解InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会另辅助索引变得过大。