【面试实战篇】说一说MySQL中的索引
这种属于泛问题,索引是一个很大的话题,遇到这种泛问题,其实可以说的内容非常非常多,你完全可以说个几分钟,一顿操作来证明一下自己的功底,而不是一脸懵逼,不知道回答啥好。
那对于这种泛问题,我们应该怎么去回答呢?
首先我们一定要有逻辑 + 流畅,一般可以这样:你可以先把能说的知识点罗列出来,然后进行有逻辑的拼凑,比如对于索引这个话题,可以说的知识点有(这个时候就看你自己平时的积累了):
1、索引底层结构(B+树)+ 为什么选择了 B+ 树
2、索引类型 + 不同类型的存储结构不同
3、不同引擎中,索引的底层结构会不同(一般强调InnoDB)
4、索引失效的情况
5、选择索引的规则
6、加了索引不一定快
7、优化器什么时候会选择索引什么时候不选择
8、…..
我们不一定需要全说,因为有些你说了 A 知识点,其实就已经证明了你会 B 知识点了,比如我说了知识点「7」,优化器我都懂,难道面试官会觉得你不懂「1」吗?但是你也不能一上来就讲优化器,说不定面试官也不懂这东西,所以你要一点一点来,由浅入深。
下面我先演示一下我的回答(注意条条大路通罗马,我这里只是一个例子)
平时我们看书的时候,会有一个目录,我们可以通过这个目录更快着定位到我们想要找的内容在第几页,其实 MySQL 的索引之所以能加快查询也是基于这种类似的原理。
然后在 MySQL 中,有多种引擎,不同的引擎,它的索引结构等各方面也会有所不同,所以我这里主要讲一讲 INNODB 引擎相关的吧。
在 INNODB 引擎中,索引的存储方式是选择了 B+ 树这种数据结构来存储,因为 B+ 树的节点是有序的,查找起来很快,而且所有的内容都会存在于叶子节点上,加上这个叶子结点是通过双向链表来串联的,这对于范围查找就非常合适,而范围查找在 MySQL 中是经常出现的操作。
当然,除此之外,也有很多其他优点了,比如 B+ 树这种存储结构,他的非叶子结点只存放 key,不存放 value,这样一个磁盘页就可以加载更多节点,这减少磁盘加载到内存的次数。
虽然索引能够加快查询效率,不过呢,在写 SQL 语句的时候,也要注意一些规则,因为如果操作不当会导致索引失效,比如你在 SQL 语句中进行函数操作可能就会导致索引失效。
另外,虽然索引能够加快查询效率,但其实这也不是绝对的,有时候不走索引可能比走索引还要快,所以有时你即使正确加了索引,SQL 语句书写也正常,系统也有可能不走索引的,要不要走索引,系统会自己进行分析,系统主要是通过索引的区分度来进行判断的,一个索引上不同的值越多,意味着出现相同数值的索引越少,意味着索引的区分度越高,一个索引的区分度越大,意味着走索引查询越有优势,反之则越没有优势。
所以有时候,系统如果觉得走了索引需要扫描更多行数的话,它就不走索引了,而是选择扫描全表。
当然,系统有时候也会预测错误,因为系统是通过遍历部分数据,也就是通过采样的方式,来预测索引的区分度的,有时候采样出现了比较大的误差,就会判断错误,以至于本来走索引更快的,它却扫描了全表。
不过呢,我们也能通过在 MySQL 语句加上 force 关键字来强制系统走索引了。
然后大概就说这么多。
分析一下我的模版以及建议
上面就是我平时面试的回答模版,这套回答,基本向面试官证明了我深厚的积累。当然,我一开始也无法这样回答,因为没有准备,后面每次面试,基本都会遇到这些问题,我才准备了一个模版。
然后大家发现没有,我说的东西,都是按照自己的理解来说的,不会那么死板,比如我说索引底层数据结构的时候,只是说了 B+ 树的优点,并没有去对比哈希表,链表,红黑树啥的,因为我觉得没必要,面试官如果想问,让他自己来问的就好了。
为什么我会觉得没必要呢?原因很简单,大家都是这样说的,说了 B+ 树后,就死活要去对比一下哈希表,红黑树,面试官估计都听腻了,而且他也知道你要说啥了。
当然,我不是说不能说,而是我有更多其他的内容可以说,如果你能够像我这样,那就选择像我这样,不要总是那么老套,而是按照你的理解去说。
然后有一些需要注意的点需要说一说(当然,面试官可能直接下一题了,看我这么熟悉):
1、首先我说了 B+ 树,而且还说的自信满满,面试官说不定会问我 B+ 树是怎么分裂的,当然,这个其实问的少,如果被问到,你熟悉说出来当然好,但是如果你具体细节忘了,其实也没事的,你就大概讲一下逻辑,然后说具体细节给忘了(不过你得至少了解B+树哈)。
2、我开头用一个实际的例子来引出索引,比如书的目录。对于这一种实际例子引出的操作,我个人是十分推荐的,对于一个问题,如果可以从实际例子引出,那就找一个例子来引出,例子能真正证明你确实懂的。
3、我后面说了索引优化器相关的,就是选择走索引和选择不走索引,那么面试官是有可能问我,如果系统采样失误,那应该怎么办?总不能让它一直失误吧?
这个时候,其实我们可以通过一些命令来让系统重新统计的,这意味着,你需要掌握这样一些命令,这样被问到了,才能更加加分。
对于我上面的这个回答,大概的结果就是:
1、如果面试官对索引不是很懂,那他就直接问下一题了;
2、如果面试官对索引懂很多,他可能会更加深入问其他问题,各种连环炮问你。
有人可能会担心,回答这么多,被面试官连环炮更加深入问,问到不懂的怎么办?会不会因此被扣分?
这个其实你不用担心,被问到不懂的知识点,直接说不懂就好了,面试官并不会因为你不懂,就扣你很多分啥的,毕竟你已经回答的很好了,如果问到懂的,你就再次进行一波输出。
反正我上面那段话,是有很多可以继续提问的,你也可以埋点,但个人是不大建议刻意埋点的,因为没必要吧,如果面试官想问你,你随便说啥,他都能继续挖出来问你。
多说多练
有人可能会说,那么多问题,我也不可能每个问题都准备模版啊,改怎么办?
我们不需要每个问题都准备,只需要对一些高频的问题多准备准备,多说一说,多扯一扯,扯多了,慢慢的,你就会扯了,即使这道题你没有准备过模版,你也能够流畅 + 有逻辑说出来。
这里推荐大家,准备个十几二十道题,刻意练习几次,应该就差不多了。