当前位置: 首页 > 后端技术 > Java

在线面试官MySQL索引文章

时间:2023-04-01 14:26:04 Java

面试官:我看到你简历上写的是MySQL,你知道MySQLInnoDB引擎的索引吗?考生:嗯,使用索引可以加快查询速度。其实就是把无序的数据变成有序的(排序可以加快检索速度)。考生:在InnoDB引擎中,索引的底层数据结构是一个B+树面试官:那为什么不用红黑树或者B树呢?考生:MySQL的数据是存储在硬盘上的,一般不可能在查询的时候把所有的数据“一下子”加载到内存中。考生:红黑树是“二叉查找树”的变种。一个Node节点只能存储一个Key和一个Value候选:B树和B+树不同于红黑树。它们是“多路搜索树”。与“二叉搜索树”相比,一个Node节点可以存储更多的信息,“多路搜索树”的高度会低于“二叉搜索树”。考生:理解了区别之后,其实很容易发现,在数据不能一次性加载到内存的场景下,需要对数据进行取回。选择B或B+树的理由很充分(一个Node节点存储的信息更多(相对于二叉搜索树),树的高度更低,树的高度影响检索速度)考生:比较与B树一样,B+树有两个特点。考生:1、B+树的非叶子节点不存储数据。同样的数据量下,B+树更坚固。(这个应该不用解释了,数据是存储在叶子节点上的,非叶子节点的存储可以存放更多的索引,所以整棵树会更短)考生:2.一个B+树的叶子节点组成一个链表,方便遍历查询(遍历操作在MySQL中比较常见)考生:稍微解释一下,可以填图考生:我们在MySQLInnoDB引擎下创建一个索引,相当于生成一个索引B+树。候选:如果索引是“聚集(clustered)索引”,那么当前B+树的叶子节点存放的是“当前行的主键和数据”候选:如果索引是“非聚集索引”,那么当前B+树的叶子节点存放的是“主键和当前索引列值”的候选:比如写一句sql:select*fromuserwhereid>=10,那么只需要定位到id为10的记录,然后在叶子节点之间传递遍历完链表(由叶子节点组成的链表),就可以找到后面的记录了。考生:由于B树也是在非叶子节点存储数据,所以遍历的时候可能要跨层查找,比较麻烦。考生:基于树的层次结构和业务使用场景的特点,MySQL选择了B+树作为索引的底层数据结构。考生:对于hash结构,InnoDB引擎其实是一个“自适应”的hash索引(hash索引的创建是由InnoDB存储引擎引擎自动优化创建的,我们无法干预)面试官:嗯……那我懂了,对了,你知道什么叫returnform吗?考生:所谓的表返回其实就是,当我们使用索引查询数据时,检索到的数据可能包含其他列,但是索引树的叶子节点只能找到当前列值和主键ID,所以需要根据主键ID再次查数据,得到SQL需要的候选列:比如我这里为订单号ID建了一个索引,但是我的SQL是:selectorderId,orderNamefromorderdetailwhereorderId=123candidatesAuthor:SQL有一个orderID索引,但是orderID索引树的叶子节点只有orderId和Id,而我们要检索orderName,所以MySQL会得到ID,然后找出orderName并将其返回给我们。这个操作就是Callbacktablecandidates:如果想避免回表,也可以使用覆盖索引(能用就用,因为它避免了回表)。考生:所谓覆盖索引,其实就是你要查找的列刚好存在于叶子节点上。比如我建了一个orderId和orderName的联合索引。我只需要查询orderId和orderName。这些数据都存在于索引树的叶子节点上,不需要回表。面试官:既然你也提到了联合索引,请问你了解最左匹配原则吗?考生:嗯,解释一下这个概念,举个例子更容易说明考生:如果有一个索引(a,b,c,d),查询条件a=1andb=2andc>3andd=4,那么会在每个结点依次命中a、b、c,不能命中d个候选:先匹配最左边的,索引只能用来查找key是否存在(相等)。遇到范围查询(>,<,between,likeLeftmatching)等,无法进一步匹配,后续退化为线性搜索候选:这就是最左匹配原则面试官:嗯,我也想请问你的主键是怎么生成的?应试者:主键是自增的面试官:如果我不使用MySQL的自增主键,你觉得会有什么问题?考生:首先,主键要保证它的唯一性和空间尽可能的短。需要考虑这两件事。考生:另外,由于索引的性质(有序),如果生成类似uuid的主键,插入的性能比自增差。候选:因为生成的uuid在插入Disk块的时候可能需要移动(比如当前时刻块中的空间已经满了,但是新生成的uuid需要插入到满块中,而block的数据block需要移动)面试官:OK...本文总结:为什么是B+树?数据不能一次加载到内存中。B+树是一种多路搜索树。只有叶子节点存储数据,叶子节点之间的链表是关联的。(树矮,容易遍历)什么是回表?非聚集索引只在叶子节点中存储列值和主键ID。如果条件允许,尽量使用覆盖索引,避免回表操作,提高查询速度。什么是最左匹配原则?从最左边开始连续匹配。如果范围查询终止时主键不自增会怎样?插入效率下降,移动块出现数据问题