你都理解MySQL索引的这些高频面试题吗?
前言
作为 Java 开发人员或者后端开发人员,面试中永远避不了数据库中索引,这些问题有时候真的非常头疼,特别是面试官不仅仅会考察基础知识,还会结合简历上的项目经验,所以我们非常有必要彻底吃透索引。当然啦,作为关系型数据库的代表,MySQL 一直在不断发展壮大中,MySQL 索引也成为了大规模高并发业务场景的利器。今天收集了一些经典且高频的MySQL 索引面试题,希望能够帮助到小伙伴们~
1. MySQL 支持哪些存储引擎?
【参考答案】
MySQL 支持的存储引擎主要有四种:
(1)InnoDB 支持事务,行级锁定和外键,是事务型数据库的首选引擎;MySQL5.5.5 之后的默认存储引擎;
(2)MyISAM 拥有较高的插入、查询速度,但不支持事务。MySQL5.5.5 之前的默认存储引擎;
(3)Memory 基于散列,存储在内存中,对临时表有用。常见的应用场景是:临时存放数据,数据量不大,并且不需要较高的数据安全性;
(4)Archive 支持高并发的插入操作,但是本身不是事务安全的。常见的应用场景:存储归档数据,如记录日志信息可以使用 Archive。
2. InnoDB 和 MyISAM 有什么区别呢?
【参考答案】
InnoDB 支持事务;而 MyISAM 不支持事物,强调的是性能,查询速度更快; InnoDB 支持行级锁和表级锁(默认行级锁),而 MyISAM 只支持表级锁; InnoDB 支持 MVCC, 而 MyISAM 不支持 MVCC; InnoDB 支持外键,而 MyISAM 不支持外键; InnoDB早期版本不支持全文索引(从 MySQL5.6 开始支持全文索引),而 MyISAM 支持; InnoDB 不保存表的具体行数,count () 时要扫描一遍整个表来计算有多少行;MyISAM 则内置了一个计数器,count () 时它直接从计数器中读。
注意:在 MySQL 中,索引就是在存储引擎层实现的,不同存储引擎的索引的工作方式并不一样,即使不同的存储引擎支持同一种类型的索引,其底层的实现也可能不同。而这些存储引擎中以 InnoDB 应用最广泛,很多面试题也围绕着它展开。
3. MySQL 索引底层是什么结构?选择采用此结构有什么好处?
【参考答案】
MySQL 索引底层采用 B + 树的存储结构。采用 B + 树的原因:
(1)索引文件很大,不能全部存储在内存中,只能存储到磁盘上,因此索引的数据结构要尽量减少查找过程中磁盘 I/O 的存取次数;
(2)数据库系统利用了磁盘预读原理和磁盘预读,将一个节点的大小设为等于一个页,这样每个节点只需要一次 I/O 就可以完全载入。而 B + 树的高度是 2~4,检索一次最多只需要访问 4 个节点(4 次,即树的高度)。
4. 为什么不选择 B 树?
【参考答案】
B + 树所有的 Data 域在叶子节点,其余节点用来索引,而 B 树是每个索引节点都会有 Data 域;并且 B + 树所有叶子节点之间都有一个链指针。这样遍历叶子节点就能获得全部数据,从而支持区分查询。在数据库中基于范围的查询是非常频繁的,而 B 树不支持这样的遍历操作。
5. 为什么不选择哈希表?
【参考答案】
哈希表只适用与查找等值查询, 不能支持区分条件(大于小于查询)、模糊查询等; hash 索引虽然在等值查询上较快,但是不稳定,性能不可预测,当某个键值存在大量重复的时候,发生 hash 碰撞,此时效率可能极差。而 B + 树的查询效率比较稳定。
6. 为什么不选择红黑树?
【参考答案】
红黑树往往高度过大,从页造成磁盘 IO 读写过于频繁,效率低下。而且逻辑上很近的节点(父子)物理上可能很远,无法利用局部性原理。
7. MySQL 支持的索引类型是哪些?
【参考答案】
普通索引:用表中的普通列构建的索引,没有任何限制; 唯一索引:唯一索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一; 主键索引:是一种特殊的唯一索引,根据主键建立索引,不允许重复,不允许空值; 全文索引:通过过建立倒排索引,快速匹配文档的方式。MySQL 5.7.6 之前仅支持英文,MySQL 5.7.6 之后支持中文; 组合索引:又叫联合索引。用多个列组合构建的索引,这多个列中的值不允许有空值。可以在创建表的时候指定,也可以修改表结构。
8. 知道聚集索引和非聚集索引吗?
【参考答案】
聚集索引 (clustered index),又称为主索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序。因为数据真正的数据只能有一种排序方式,所以一个表上只能有一个聚簇索引。 非聚集索引 (secondary index),又称为辅助索引、普通索引,该索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表可以包含多个非聚集索引。
注意:聚集索引 / 非聚集索引不是一种索引类型,而是一种存储数据的方式。在 InnoDB 中它们还有一个非常重要的区别:聚集索引的叶子节点的的 data 域包含了完整的数据记录,而非聚集索引的叶子节点的 data 域记录着主键的值,因此在使用非聚集索引进行查找时,需要先查找到主键值,然后再到聚集索引中进行查找,这称之为回表查询。
9. 索引什么时候会失效?
【参考答案】
索引失效通常有以下原因:
条件中有 or; like 查询(以 % 开头); 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引; 对列进行函数运算(如 where md5 (password) = “xxxx”); 负向查询条件会导致无法使用索引,比如 NOT IN,NOT LIKE,!= 等; 对于联合索引,不是使用的第一部分 (第一个),则不会使用索引(最左匹配); 如果 mysql 评估使用全表扫描要比使用索引快,则不使用索引;。
追问:表 A 建立了 INDEX (col1,col2,col3) 的联合索引,where 条件中使用 col1 = a1 and col3=c1 索引是否有效?
答案:索引有效。
10. 索引有什么缺点?
【参考答案】
索引需要额外的占用物理空间,索引越多,所以空间越多; 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的写入速度;
总结
MySQL 索引既是 MySQL 面试中的高频题,也是项目中可以提高生产力的有力工具,实践性非常强,因此强烈建议大家在项目多多实践,才能灵活运用索引,实践出真知嘛