本文转载自微信公众号《IT行业的打工仔》,作者:LeoWu。转载本文请联系IT行业农民工公众号。前段时间有读者建议聊聊指数下推,本期就安排这件事。多余的前言我就不重复了,直接开始吧。大家坐下!-思维导图-回表操作对于数据库来说,只要涉及到索引,就没有办法绕过回表操作。当然,这也是我们今天要说的基础。说回表,就要从索引说起。别着急,就不长篇大论了,这里只是简单的说说主键索引和普通索引,目的是让大家对回表操作有个了解。如果熟悉背表操作,可以跳过这一段。这里我们只以Innodb存储引擎作为讲解的对象。主键索引主键索引的底层数据存储是通过B+树实现的。简单来说,除叶节点外的所有节点都存储主键值。叶节点存储整行数据。总体结构如下图所示。非主键索引除主键索引外,其他索引都称为非主键索引。与主键索引不同,非主键索引的叶子节点存储的是主键的值。那我们回到最初的问题,什么是回表操作?当我们在非主键索引上查找一行数据时,此时的查找方式是先查找非主键索引树,得到对应的主键值。然后去主键索引树中找到对应的行数据。这种操作称为回表操作。好了,到这里你应该明白什么是回表操作了。简单来说,就是在非主键索引树上获取对应的主键值,然后返回到主键索引中,找到对应的行数据。这样做的前提是非主键索引树上不存在要查找的字段。低版本操作说完了回表操作,让我们继续回到本文的主题——索引下推。其实Mysql在5.6版本之前是没有索引下推功能的,5.6版本之后才增加了这个优化项。那么在介绍索引下推之前,我们先回顾一下没有这个功能如何处理。让我们用一个真实的例子来解释。这里有一个用户表user,记录了用户的姓名、性别、身高、年龄等信息。表中id为自增主键,(name,sex)为联合索引。在这里使用1代表男性,2代表女性。现在我们需要找出所有王姓男性的信息。SQL实现起来很简单:但是它的实现原理是什么?根据联合索引的最左前缀原则,当我们在非主键索引树上找到第一个满足条件的值时,返回叶节点记录的主键值。在主键索引树上找到对应的行数据,然后比较是否是你当前要找的性别。整个原理可以用下图来表示。你看,在低版本中,每条数据都需要返回到表中,增加了树查找的次数。如果要查找的数据量很大,那么性能肯定有所欠缺。高版本操作说完低版本操作,让我们继续回到本文的主题——索引下推。知道了痛点,那么如何解决。很简单,满足条件才能返回表。结合我们的例子,当性别sex=1满足时,再回表查。这样一来,本来可能需要4次查表回表,现在可能只需要2次。所以本质上,索引下推就是满足条件才回表,先判断索引包含的字段,不满足条件的跳过。减少不必要的返台操作。回表操作总结当要查找的字段不在非主键索引树上时,需要通过叶子节点的主键值从主键索引中获取对应的行数据。这个过程称为表回操作。索引下推索引下推主要是减少不必要的回表操作。对于找到的数据,先过滤掉不符合条件的,然后在主键索引树上查找剩下的。
