zoukankan      html  css  js  c++  java
  • InnoDB与MyISAM的区别

    InnoDB和MyISAM是很多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,5.7之后就不一样了

    1、事务和外键

    InnoDB具有事务,支持4个事务隔离级别,回滚,崩溃修复能力和多版本并发的事务安全,包括ACID。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能

    MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择

    2、全文索引

    Innodb不支持全文索引,如果一定要用的话,最好使用sphinx等搜索引擎。myisam对中文支持的不是很好

    不过新版本的Innodb已经支持了

    3、锁

    mysql支持三种锁定级别,行级、页级、表级;

    MyISAM支持表级锁定,提供与 Oracle 类型一致的不加锁读取(non-locking read in SELECTs)

    InnoDB支持行级锁,InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,注意间隙锁的影响

    例如update table set num=1 where name like “%aaa%”

    4、存储

    MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型, .frm文件存储表定义,数据文件的扩展名为.MYD,  索引文件的扩展名是.MYI

    InnoDB,基于磁盘的资源是InnoDB表空间数据文件和它的日志文件,InnoDB 表的大小只受限于操作系统文件的大小

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

    5、索引

    InnoDB(索引组织表)使用的聚簇索引、索引就是数据,顺序存储,因此能缓存索引,也能缓存数据

    MyISAM(堆组织表)使用的是非聚簇索引、索引和文件分开,随机存储,只能缓存索引

    6、并发

    MyISAM读写互相阻塞:不仅会在写入的时候阻塞读取,MyISAM还会在读取的时候阻塞写入,但读本身并不会阻塞另外的读

    InnoDB 读写阻塞与事务隔离级别相关

    7、场景选择

    MyISAM

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

    InnoDB 

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

    8、其它细节

    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表

    7、为什么MyISAM会比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时这种策略是如何应用到特定的操作的

    SELECT InnoDB必须每行数据来保证它符合两个条件

    1、InnoDB必须找到一个行的版本,它至少要和事务的版本一样老(也即它的版本号不大于事务的版本号)。这保证了不管是事务开始之前,或者事务创建时,或者修改了这行数据的时候,这行数据是存在的。

    2、这行数据的删除版本必须是未定义的或者比事务版本要大。这可以保证在事务开始之前这行数据没有被删除。

    8、mysql性能讨论

    MyISAM最为人垢病的缺点就是缺乏事务的支持

    InnoDB 的磁盘性能很令人担心

    MySQL 缺乏良好的 tablespace 

  • 相关阅读:
    一道打印的面试题
    Quartz使用总结
    子类和父类之间的静态代码块、静态方法、非静态代码块、构造函数之间的执行关系
    springboot使用 @EnableScheduling、@Scheduled开启定时任务
    springboot的Interceptor、Filter、Listener及注册
    ConcurrentHashMap 的工作原理及代码实现
    为什么Hashtable ConcurrentHashmap不支持key或者value为null
    Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解
    Android 自定义title 之Action Bar
    Android常用控件之GridView与ExpandableListView的用法
  • 原文地址:https://www.cnblogs.com/terryguan/p/4531851.html
Copyright © 2011-2022 走看看