这个问题简单回答一下即可
面试官:MySQL的引擎都有哪些?
我:我知道,MySQL内部可以分为服务层和存储引擎层两部分:服务层包括连接器、查询缓存、分析器、优化器、执行器等;存储引擎层负责数据的存储和提取。我就说一下自己了解的InnoDB和MyISAM引擎
- 是 MySQL 默认的事务型存储引擎,只有在需要它不支持的特性时,才考虑使用其它存储引擎。
- 实现了四个标准的隔离级别,默认级别是可重复读(REPEATABLE READ)。在可重复读隔离级别下,通过多版本并发控制(MVCC)+ (Next-Key Locking)防止幻影读。
- 主索引是聚簇索引,在索引中保存了数据,从而避免直接读取磁盘,因此对查询性能有很大的提升。
- 内部做了很多优化,包括从磁盘读取数据时采用的可预测性读、能够加快读操作并且自动创建的自适应哈希索引、能够加速插入操作的插入缓冲区等。
- 支持真正的在线热备份。其它存储引擎不支持在线热备份,要获取一致性视图需要停止对所有表的写入,而在读写混合场景中,停止写入可能也意味着停止读取。
- 设计简单,数据以紧密格式存储。对于只读数据,或者表比较小、可以容忍修复操作,则依然可以使用它。
- 提供了大量的特性,包括压缩表、空间数据索引等。
- 不支持事务。
- 不支持行级锁,只能对整张表加锁,读取时会对需要读到的所有表加共享锁,写入时则对表加排它锁。但在表有读取操作的同时,也可以往表中插入新的记录,这被称为并发插入(CONCURRENT INSERT)。
我一般还会回答一个索引文件上的区别
- MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址,同样使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址
- 在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复
- MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录
- InnoDB的数据文件本身就是索引文件,这棵树的叶节点data域保存了完整的数据记录(聚集索引)
- InnoDB的辅助索引data域存储相应记录主键的值而不是地址
- 聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
其实个人还知道一点,分页查询的时候还有一点区别,这点区别也是根据索引文件的区别来的。
咱们知道,使用limit分页查询,offset越大,性能越差,比如:
-- 以真实的生产环境的6万条数据的一张表为例,比较一下优化前后的查询耗时:
-- 传统limit,文件扫描
select * from table order by id limit 50000,2;
受影响的行: 0
时间: 0.171s
-- 子查询方式,索引扫描
select * from table
where id >= (select id from table order by id limit 50000 , 1)
limit 2;
受影响的行: 0
时间: 0.035s
-- JOIN分页方式
select * from table as t1
join (select id from table order by id limit 50000, 1) as t2
where t1.id <= t2.id order by t1.id limit 2;
受影响的行: 0
时间: 0.036s
原因:因为 MySQL 并非是跳过偏移量直接去取后面的数据,而是先把偏移量+要取的条数,然后再把前面偏移量这一段的数据抛弃掉再返回的。比如上面的(50000,2),每次取2条,还要经过回表,发现不是想要的,舍弃。那肯定非常耗时间,而通过子查询通过id索引,只查询id,使用到了innodb的索引覆盖, 在内存缓冲区中进行检索,没有回表查询. 然后再用id >= 条件,进一步的缩小查询范围.这样就大大提高了效率。
而MyISAM,是直接索引是分离的,通过索引文件查到的数据记录地址,不需要回表,直接对应数据记录,效率也很高。