标签:两者之间 事务 索引 innodb MyISAM InnoDB 主键
MyISAM与InnoDB两者之间区别与选择,详细总结,性能对比1、MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,而且不支持外键,如果执行大量的select,insert MyISAM比较适合。 2、InnoDB:支持事务安全的引擎,支持外键、行锁、事务是他的最大特点。如果有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的情况。
一、表锁差异 MyISAM: myisam只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。也可以通过lock table命令来锁表,这样操作主要是可以模仿事务,但是消耗非常大,一般只在实验演示中使用。 InnoDB : Innodb支持事务和行级锁,是innodb的最大特色。 事务的ACID属性:atomicity,consistent,isolation,durable。 并发事务带来的几个问题:更新丢失,脏读,不可重复读,幻读。 事务隔离级别:未提交读(Read uncommitted),已提交读(Read committed),可重复读(Repeatable read),可序列化(Serializable) 四种隔离级别的比较
查看mysql的默认事务隔离级别“show global variables like ‘tx_isolation’; ” Innodb的行锁模式有以下几种:共享锁,排他锁,意向共享锁(表锁),意向排他锁(表锁),间隙锁。 注意:当语句没有使用索引,innodb不能确定操作的行,这个时候就使用的意向锁,也就是表锁 关于死锁: 什么是死锁?当两个事务都需要获得对方持有的排他锁才能完成事务,这样就导致了循环锁等待,也就是常见的死锁类型。 解决死锁的方法: 1、 数据库参数 2、 应用中尽量约定程序读取表的顺序一样 3、 应用中处理一个表时,尽量对处理的顺序排序 4、 调整事务隔离级别(避免两个事务同时操作一行不存在的数据,容易发生死锁)
二、数据库文件差异 MyISAM : myisam属于堆表 myisam在磁盘存储上有三个文件,每个文件名以表名开头,扩展名指出文件类型。 .frm 用于存储表的定义 .MYD 用于存放数据 .MYI 用于存放表索引 myisam表还支持三种不同的存储格式: 静态表(默认,但是注意数据末尾不能有空格,会被去掉) 动态表 压缩表 InnoDB : innodb属于索引组织表 innodb有两种存储方式,共享表空间存储和多表空间存储 两种存储方式的表结构和myisam一样,以表名开头,扩展名是.frm。 如果使用共享表空间,那么所有表的数据文件和索引文件都保存在一个表空间里,一个表空间可以有多个文件,通过innodb_data_file_path和innodb_data_home_dir参数设置共享表空间的位置和名字,一般共享表空间的名字叫ibdata1-n。 如果使用多表空间,那么每个表都有一个表空间文件用于存储每个表的数据和索引,文件名以表名开头,以.ibd为扩展名。
三、索引差异 1、关于自动增长 myisam引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。 innodb引擎的自动增长咧必须是索引,如果是组合索引也必须是组合索引的第一列。 2、关于主键 myisam允许没有任何索引和主键的表存在, myisam的索引都是保存行的地址。 innodb引擎如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见) innodb的数据是主索引的一部分,附加索引保存的是主索引的值。 3、关于count()函数 myisam保存有表的总行数,如果select count(*) from table;会直接取出出该值 innodb没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre 条件后,myisam和innodb处理的方式都一样。 4、全文索引 myisam支持 FULLTEXT类型的全文索引 innodb不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。(sphinx 是一个开源软件,提供多种语言的API接口,可以优化mysql的各种查询) 5、delete from table 使用这条命令时,innodb不会从新建立表,而是一条一条的删除数据,在innodb上如果要清空保存有大量数据的表,最 好不要使用这个命令。(推荐使用truncate table,不过需要用户有drop此表的权限) 6、索引保存位置 myisam的索引以表名+.MYI文件分别保存。 innodb的索引和数据一起保存在表空间里。
四、开发的注意事项 1、可以用 show create table tablename 命令看表的引擎类型。 2、对不支持事务的表做start/commit操作没有任何效果,在执行commit前已经提交。 3、可以执行以下命令来切换非事务表到事务(数据不会丢失),innodb表比myisam表更安全:alter table tablename type=innodb;或者使用 alter table tablename engine = innodb; 4、默认innodb是开启自动提交的,如果你按照myisam的使用方法来编写代码页不会存在错误,只是性能会很低。如何在编写代码时候提高数据库性能呢? a、尽量将多个语句绑到一个事务中,进行提交,避免多次提交导致的数据库开销。 b、在一个事务获得排他锁或者意向排他锁以后,如果后面还有需要处理的sql语句,在这两条或者多条sql语句之间程序应尽量少的进行逻辑运算和处理,减少锁的时间。 c、尽量避免死锁 d、sql语句如果有where子句一定要使用索引,尽量避免获取意向排他锁。 f、针对我们自己的数据库环境,日志系统是直插入,不修改的,所以我们使用混合引擎方式,ZION_LOG_DB照旧使用myisam存储引擎,只有ZION_GAME_DB,ZION_LOGIN_DB,DAUM_BILLING使用Innodb引擎。
五、究竟该怎么选择 下面先让我们回答一些问题: ◆你的数据库有外键吗? ◆你需要事务支持吗? ◆你需要全文索引吗? ◆你经常使用什么样的查询模式? ◆你的数据有多大?
InnoDB InnoDB 给 MySQL 提供了具有事务(commit)、回滚(rollback)和崩溃修复能力 (crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。 InnoDB 提供了行锁(locking on row level),提供与 Oracle 类型一致的不加锁读取(non- locking read in SELECTs)。这些特性均提高了多用户并发操作的性能表现。在InnoDB表中不需要扩大锁定 (lock escalation),因为 InnoDB 的列锁定(row level locks)适宜非常小的空间。 InnoDB 是 MySQL 上第一个提供外键约束(FOREIGN KEY constraints)的表引擎。
六、重复地总结一遍 1、MyISAM不支持事务,InnoDB是事务类型的存储引擎,当我们的表需要用到事务支持的时候,那肯定是不能选择MyISAM了。 2、MyISAM只支持表级锁,BDB支持页级锁和表级锁默认为页级锁,而InnoDB支持行级锁和表级锁默认为行级锁 行级锁:只对指定的行进行锁定,其他进程还是可以对表中的其他行进行操作的。 3、MyISAM引擎不支持外键,InnoDB支持外键 4、MyISAM引擎的表在大量高并发的读写下会经常出现表损坏的情况 Incorrect key file for table: '...'. Try to repair it 对于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个query, 表记录总数:38万 , 时间单位 s (1)加了索引以后,对于MyISAM查询可以加快:4 206.09733倍,对InnoDB查询加快510.72921倍,同时对MyISAM更新速度减慢为原来的1/2,InnoDB的更
七、性能对比
测试的版本是mysql Ver 14.14 Distrib 5.1.49, for debian-linux-gnu (i686),使用的是Innodb plugin 1.0.8(官方称比built-in版本性能更好)和默认的MyISAM。 测试机器是笔记本,配置如下:Intel 酷睿2双核 P8600,2G*2 DDR3 1066内存,320G硬盘5400转。 测试一:数据插入性能测试,这里我分别对innodb_flush_log_at_trx_commit参数打开和关闭都测了了一下,每次测试都是运行40s,表中数字都是实际插入条数。 单线程,逐个插入 120000 60000 60000 4线程,逐个插入 40000*4 单线程,批量100条/次插入 3600*100 单线程,批量200条/次插入 1800*200 可以发现批量插入的性能远高于单条插入,但是一次批量的大小对性能影响不大。每条记录是否都刷新日志的参数对innodb性能的影响巨大。总体上来说,MyISAM性能更优一点。这里有一点需要注意,在插入测试过程中,我对系统资源进行了监控,发现MyISAM对系统资源占用很低,但是Innodb对磁盘占用却很高,应该是对事务控制多了很多需要记录的日志。 测试二:数据读取性能测试。每次随机读取1000条记录,反复进行读取。 单线程,200次读取 5.7s 4线程,200次读取 12s 可以看出MyISAM的读取性能非常恐怖,性能差距在3倍的样子。 以上两个测试发现MyISAM在无事务的需求下几乎完胜,但是要知道它是表锁,Innodb是行锁,那么在并发读写同时存在的情况下,那结果会是怎么样呢?! 测试三:两个线程并发写入,2个线程并发读取。 逐个插入 写入40s:10000*2 批量100条/次插入 写入40s:1000*100*2 读取200次*2:10s 写入40s:1500*100*2 读取200次*2:50s 这下立刻显示出Innodb在并发情况下强劲的性能,几乎没有什么性能衰减。而MyISAM单条插入速度变得非常慢,批量插入也下降了40%性能。 总结一下,在写多读少的应用中还是Innodb插入性能更稳定,在并发情况下也能基本,如果是对读取速度要求比较快的应用还是选MyISAM。
转自于:http://blog.csdn.net/wjtlht928/article/details/46641865 |
标签:两者之间,事务,索引,innodb,MyISAM,InnoDB,主键 来源: https://www.cnblogs.com/xingkongzhizhu/p/12003572.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。