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

一篇文章把MySQL的clustering-join-coveringindex,tablereturn,indexpushdown解释的很清楚

时间:2023-04-02 09:21:46 Java

你的面试官来找你,穿着格子衬衫,啤酒肚,是个发际线严重后退的中年男人。年轻人。手里拿着泡了枸杞子的保温杯,胳膊下夹着一台MacBook,MacBook上贴着公司标语:“加班让我快乐”。面试官:看你简历上用过MySQL,我问你几个简单的问题。什么是聚簇索引和非聚簇索引?这个问题帮不了我。来之前先看一下MySQL的八字八卦。我:比如:有这么一张用户表CREATETABLE`user`(`id`intCOMMENT'主键ID',`name`varchar(10)COMMENT'name',`age`intCOMMENT'age',PRIMARYKEY(`id`))ENGINE=InnoDBCHARSET=utf8COMMENT='用户表';这些数据存储在用户表中:idnaneage1一灯182张三223李四214王二195马子20那么在索引中,这些数据是如何存储的呢?MySQL的InnoDB引擎中的索引使用的B+树结构。不要问为什么根节点存储(1,4)两个元素,左子节点存储(1,2,3)三个元素,下面还有3个叶子节点,叶子节点之间是有序连接的链表?问题是B+树的特性。不明白的可以看上一期的文章。如上图所示,所有元素的索引都存储在叶子节点中,也就是簇索引。通常,主键索引是聚集索引。如果表中没有主键,MySQL也会默认创建一个隐藏主键作为主键索引。什么是非聚集索引?假设我们在age(年龄)字段上建立一个普通的索引,age字段上的索引存储结构如下:叶子节点只存储当前索引字段和主键ID,这样的存储结构是非聚簇索引。采访者:那什么是联合指数呢?我:由多个字段组成的索引就是联合索引。面试官:[晕]建立联合索引有什么好处?它与在单个字段上建立索引有何不同?我:假设有这么一条查询语句。select*fromuserwhereage=18andname='ZhangSan';如果我们分别在age和name字段上建立两个索引,那么这条查询语句只会使用其中一个索引。但是我们在age和name字段上建立一个联合索引(age,name),它的存储结构就变成了这样。如果只在age上建索引,会先在age上查询非聚集索引,有3条age=18的记录,主键ID分别为1、4、5,然后用这3个ID去查询主键ID索引的聚类。如果在age和name上建联合索引,会先在age和name上查询非聚集索引,匹配一条记录,主键ID为1,然后用这个ID查询主的聚集索引密钥ID。可以总结出联合索引的优点:大大减少了扫描的行数。面试官:再说一遍什么是最左匹配原则?我:最左匹配原则是指在创建联合索引时,以最左为优先,从最左开始的任何连续索引都可以匹配。当我们在(age,name)上创建联合索引时,where条件中只有age可以使用索引,age和name也可以使用索引。但是当只有名字的时候,就不能使用索引了。为什么会这样?看上图可以理解,(age,name)的联合索引是先按年龄排序,年龄相等的行按姓名排序。如果where条件只有一个名字,当然不能使用索引。面试官:什么是覆盖索引和回表查询?我:这个更简单,这个知识点上面已经讲过了。当我们在年龄上建立索引时,查询SQL是这样的:selectidfromuserwhereage=18;会用到覆盖索引,因为我们在用age索引的时候已经把id字段查出来了,下次查询不需要重新回表。但是当查询SQL是这样的:select*fromuserwhereage=18;如果要查询所有字段,需要两次查询回表。因为我们第一次使用年龄索引的时候只是查到了主键ID,所以我们还需要使用主键ID回表查询所有的字段。面试官:还有一个问题,你知道什么是指数下推吗?能问出这么冷门的问题,造火箭还真得面试啊!我:IndexConditionPushdown是MySQL5.6引入的索引优化特性。示例:在(age,name)上建立联合索引并查询SQL时:select*fromuserwhereage=18andname='ZhangSan';如果没有索引下推,则先匹配age=18的三条记录,然后使用ID回表查询,过滤掉name='张三'的记录。如果下推索引,会先匹配3条age=18的记录,然后过滤掉一条name='张三'的记录,最后将id返回到表中进行查询。由此可见,索引下推的好处是减少了扫描回表的行数。面试官:小伙子,你背八股文很流利。我会给你一个实际的问题,看看你是否准备好了。下面查询SQL如何建立联合索引?从表中选择a,其中b=1且c=2;刁难我?你以为实践题八股作文背不下来?我:刚才讲联合索引的时候已经提到了这个知识点。where条件有b和c的等值查询,建立联合索引(b,c)。由于select后面有a,我们建(b,c,a)的联合索引可以用来覆盖索引,查询速度更快。采访者:小伙子,有件事。一会儿给你发offer,明天我就来双倍工资上班。文章持续更新中,大家可以在微信搜索“一光架构”第一时间阅读更多技术干货。