面试官:
你好,不要太紧张,看简历上写着你对MySql比较熟悉,那我们先来聊聊MySql吧。
三毛:
嗯嗯,好的,我们项目中基本都用到了MySql,对这块应该还是比较熟悉的。
面试官:
好,那我们聊一聊MySql的数据库引擎,你知道MySql的数据库存储引擎吗?
三毛:
我了解MySql是有两种数据库引擎,一种是MyISAM,一种是InnerDB, MyISAM不支持事务,只支持表级锁,对于有事务需求或者是增删改比较频繁的表不适合用这种引擎。 InnerDB增加了redo log日志,支持事务,并且支持行锁,开发中大多数都是用的这种引擎。
面试官:
嗯,好的,还有吗?
三毛:
额,我能想到的基本就是这些。
面试官:
好的,那我再问下,你了解MySql的故障恢复吗?
三毛:
哦,这个我了解,InnerDB是通过binlog和redo log来支持故障恢复的,它就是记录日志的时候,先写redo log,再写binlog, 成功之后再提交redo log,标记本次操作成功。对了,MyISAM是不支持故障恢复的,这也是MyISAM和InnerDB的一个区别。
面试官:
好,那你能讲讲MySql的InnerDB存储引擎崩溃恢复具体流程吗?
三毛:
这个,我只知道只要 redo log 和 binlog 保证持久化到磁盘,就能确保 MySQL 异常重启后,数据可以恢复。 具体的流程我不是很了解。
面试官:
好的,没关系,大体是这样,但是其中还有很多细节,你可以去了解一些,我们接着聊下一个, 看你在日常开发中还做过sql调优这方面的工作,讲一下你的调优方法吧。
三毛:
好的,我们在日常开发中,一般是用的阿里的Druid数据库连接池,它提供了一个sql监控页面,我们可以通过页面去查找一些 慢请求以及一些高频请求,针对慢请求,我们要去分析这个sql的执行计划,是否用到了索引,没走索引需要根据具体的sql分析 是没加索引还是避开了索引,没加索引我们要考虑加上索引,避开了索引我们要想办法优化sql,避免一些常规的不走索引的, 例如:全模糊查询,or查询或者函数操作等等。而针对高频请求,我们会对请求进行分析,确定其是否需要每次都走DB, 有些高频请求可以加上缓存,提高响应效率,减少DB压力。
面试官:
嗯,思路是对的,那我们再来聊一下MySql的索引,你了解MySql的索引数据结构吗?
三毛:
MySql的索引结构有HASH,B+树,我们建索引一般使用的是B+树,因为HASH不支持范围查询以及排序。而B+树因为 它的数据结构特点,可以支持范围查找,排序等。
面试官:
好的,那你能讲讲为什么MySql会选择B+树作为索引结构呢,支持顺序的结构有很多啊,像数组,平衡二叉树等?
三毛:
确实支持顺序的结构有很多,数组它的缺点是插入的效率太低,需要移动元素,若是大表,里面数据量很多,如果你是非自增 主键的话,那将一条记录插入到数组中间某个地方,那这个效率就差了。而二叉树,它然也支持顺序遍历,但是数据量大了, 它的树高就比较大了,100万数据的话大概树高20,要访问20次磁盘,这个效率也是比较低的,而b+树却正好符合MySql的需求。
面试官:
那单是树高的话,还有B树啊,为什么非要选择B+树呢?
三毛:
这个,我就不是很了解了。
面试官:
你可以从它们的数据结构特点去分析一下。
三毛:
B树的话,它的每个子节点都是存储具体的数据的,而B+树它的数据都存储在叶子节点上,叶子节点是一个链表, 当你要查询一个区间的话,查询B+树,有点类似于跳表,可以快速定位到起点,然后从叶子节点往后查, 直到不符合区间范围。相比于查询B树的话,效率应该会低点。
面试官:
面带微笑:不错,大概是这么回事,不过B树的结构你没讲到,是对B树没去了解过吧。
三毛:
尴尬的笑了一下:是没太了解,其实B+树也是之前看MySql索引数据结构的时候,偶尔看到提了一下B+树结构才了解的。
面试官:
没关系,你可以去了解一下,我们接着聊,说说MySql的覆盖索引,前缀索引,索引下推吧。
三毛:
说到覆盖索引的话,我先说一些MySql的索引类型,有主键索引和非主键索引,主键索引对应的值记录的完整的一条数据记录, 而非主键索引记录的值是主键索引的值,当你根据非主键索引查询的时候,会先查询对应的主键的值,然后到主键索引里去查找 这条记录,这个过程称为回表,但是,当非主键索引中存在你需要查找的值的时候,比如说,你只需要查询一个主键的值,那么 这时候就会直接返回主键的值了,不需要回表,这就是覆盖索引,也就是索引里包含了你要查询的值。 前缀索引的话,B+ 树这种索引结构,可以利用索引的“最左前缀”,来定位记录。举个例子:假如我们一个表有id,name,age 字段,id是主键索引,name和age是联合索引,现在我们要查询name=‘张三’或者是name like ‘张%’的时候,可以快速定位到 name是张三或者张开头的记录,这就是前缀索引。 索引下推的话,还是上面那个例子,假如我要查找name like ‘张%’,age = 20的人的话,能够快速定位到name为张开头的 记录,MySql5.6以前,定位到name为张开头的记录后,会一个一个的回表去判断age是否符合我们的查询条件,MySql5.6以后, 找到name为张的记录后,如果索引中有查询的字段,MySql会把索引下推到age,判断age是否符合我们的查询条件,索引下推 也是避免了回表。
面试官:
嗯,这块倒是了解的不错,我在问下,你知道MySql的mvcc吗?
三毛:
mvcc就是innerDB引擎的一个支持事务的重要特性,就是多版本并发控制,我大概理解就是在不同的隔离级别下,每一个事务 开始后都会生成一个ReadView,相当于一个快照,各个事务之间修改的数据互不影响,MySql就是通过MCVCC来控制事务之间的 隔离性的。
面试官:
能说的具体点吗?比如说,如何保证事务间的隔离?
三毛:
这个,具体的流程我有点忘记了。
面试官:
嗯,好的,你有了解过MySql的主备同步吗?
三毛:
主备同步主要是通过binlog来同步,备库执行了 binlog 就可以跟主库保持一致了.
面试管:
还有吗?
三毛:
我了解的大概就是这样了。
面试管:
嗯,好的,我们今天的面试先聊到这吧,你先回去等通知。
三毛:
。。。