团队里有位成员接了个需求:按天统计出操做日志。因为系统运行有一段时间了,目前涉及的 MySQL 数据库表数据量已达到上亿,他担忧写好代码后执行 SQL 速度过慢影响性能。咱们看了下这个表用的存储引擎是 InnoDB,对于这种查询比较多的需求,若是用 MyISAM 引擎是否就好呢?html
众所周知,MySQL 有两种常见的存储引擎。一种是 MyISAM,一种是 InnoDB。mysql
我发现不少人在交流技术的时候,对英文技术名词的读法千奇百怪,甚至借助肢体语言、丰富的表情,试图表意,双方才能频频点头(潜台词:搞了半天原来你说的是这个东西啊~),因此要养成一种习惯:对于还有些模糊的技术名词,都要引起本身的兴趣去考究一番。sql
那,贴一下这两个存储引擎的单词发音吧,试着读几遍你就记住了。数据库
技术名词 | 发音 |
---|---|
MyISAM | [maɪ-zeim] |
InnoDB | [,ɪnnə-db] |
接下来咱们尝试回答几个问题。less
1、它们是什么?性能
先来看看官网对 MyISAM 的描述,只有一句话,看来官方也不想多加解释。ui
MyISAM is based on the older (and no longer available) ISAM storage engine but has many useful extensions.翻译
大意:MyISAM 是一款青出于蓝而胜于蓝的存储引擎,它在 ISAM 基础上做了一些扩展和加工。关于 ISAM ,我只告诉你它是 Indexed Sequential Access Method 的缩写,翻译为“有索引的顺序访问方法”。设计
而对 InnoDB 的描述,就更 professional 一些了。3d
InnoDB is a general-purpose storage engine that balances high reliability and high performance. In MySQL 8.0, InnoDB is the default MySQL storage engine. Unless you have configured a different default storage engine, issuing a CREATE TABLE statement without an ENGINE= clause creates an InnoDB table.
大意:InnoDB 是一种通用的存储引擎,在高可靠和高性能上做了均衡。MySQL 8.0 中,它是默认的存储引擎(其实在5.5以后的版本就是了),当你执行 CREATE TABLE 建表语句而且不带 “ENGINE = ”子句时,默认帮你建立的就是 InnoDB 表了。
2、二者有什么区别?
每一个引擎都有利有弊。
先仍是拿官网二者的 Features 来做一个分析对比吧:
一、InnoDB 是汇集索引,数据文件是和索引绑在一块儿的,必需要有主键,经过主键索引效率很高,可是辅助索引须要两次查询,先查询到主键,而后再经过主键查询到数据。所以,主键不该该过大,不然其余索引也会很大。而 MyISAM 是非汇集索引,数据文件是分离的,索引保存的是数据文件的指针,主键索引和辅助索引是独立的。
二、InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败。
三、InnoDB 在 MySQL 5.6 以前不支持全文索引,而 MyISAM 一直都支持,若是你用的是老版本,查询效率上 MyISAM 要高。
四、InnoDB 锁粒度是行锁,而 MyISAM 是表锁。
五、InnoDB 支持事务,MyISAM 不支持,对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交,这样会影响速度,因此最好把多条 SQL 语言放在 begin 和 commit 之间,组成一个事务。
六、InnoDB 不保存表的具体行数,执行 select count(*) from table 时须要全表扫描。而 MyISAM 用一个变量保存了整个表的行数,执行上述语句时只须要读出该变量便可,速度很快,但若是上述语句还包含了 where 子句,那么二者执行效率是同样的。
3、说了这么多,我到底该选哪一个?
两种存储引擎的选择,要结合你的业务场景来作选型,能够参考如下基本原则:
一、是否要支持事务,若是要请选择 Innodb,若是不须要能够考虑 MyISAM。
二、若是表中绝大多数都是读查询(有人总结出 读:写比率大于100:1),能够考虑 MyISAM,若是既有读又有写,并且也挺频繁,请使用 InnoDB。
三、系统崩溃后,MyISAM 恢复起来更困难,可否接受。
四、MySQL 5.5 开始 InnoDB 已经成为 MySQL 的默认引擎(以前是 MyISAM ),说明其优点是有目共睹的,若是你不知道用什么,那就用InnoDB吧,至少不会差。
那咱们试图来回答刚开始提到的问题:是否当初设计表结构的时候就要用 MyISAM 呢?不见得,试想一下,既然是一张用来记录操做人员的行为表,那确定涉及到大量的写操做,多人使用还涉及批量操做,逻辑复杂一点还要用到事务控制。后面的需求虽然全是读需求,但若是索引设计合理,SQL 语句写得够好,性能同样没什么问题。