前段时间有读者提议讲讲索引下推,这期就把这事儿安排上。多余的前言就不赘述了,我们直接开始。

列位坐好!

图注:思维导图

回表操作

对于数据库来说,只要涉及到索引,必然绕不过去回表操作。当然这也是我们今天所讲内容的前调基础。

说到回表,我们需要从索引开始说起。别担心,不会长篇大论,这里只是简单讲下主键索引与普通索引,目的是让大家对回表操作有个认识。如果你对回表操作很熟悉了,那么可以跳过这一段。

这里我们只以 Innodb 存储引擎作为讲解对象。

主键索引

主键索引在底层的数据存储是通过 B+ 树来实现的。简单来说,就是除叶子节之外的其他节点都存储的是主键值。而叶子节点上存储的是整行的数据。

大体结构如下图所示。

非主键索引

除了主键索引外,其它的索引都被称为非主键索引。与主键索引不同的是,非主键索引的叶子节点上存储的是主键的值。

那让我们再回到开始的问题,什么是回表操作?

当我们在非主键索引上查找一行数据的时候,此时的查找方式是先搜索非主键索引树,拿到对应的主键值,再到主键索引树上查找对应的行数据。

这种操作就叫作回表操作。

好了,这里你应该了解了什么是回表操作了。简单来讲,就是在非主键索引树上拿到对应的主键值,然后回到主键索引上找到对应的行数据。

这样做的前提条件是,所要查找的字段不存在于非主键索引树上。

低版本操作

讲完了回表操作,让我们继续回到这篇文章的主题——索引下推。

其实在 Mysql 5.6 版本之前是没有索引下推这个功能的,从 5.6 版本后才加上了这个优化项。所以在引出索引下推前还是先回顾下没有这个功能时是怎样一种处理方式。

我们以一个真实例子来进行讲解。

在这里有张用户表 user,记录着用户的姓名,性别,身高,年龄等信息。表中 id 是自增主键,(name,sex) 是联合索引。在这里用 1 表示男,2 表示女。现在需要查找所有姓王的男性信息。

SQL 实现起来很简单:

但是它的实现原理是什么呢?

根据联合索引最左前缀原则,我们在非主键索引树上找到第一个满足条件的值时,通过叶子节点记录的主键值再回到主键索引树上查找到对应的行数据,再对比是否为当前所要查找的性别。

整个原理可以用下边的图进行表示。

看到了吧,低版本中需要每条数据都进行回表,增加了树的搜索次数。如果遇到所要查找的数据量很大的话,性能必然有所缺失。

高版本操作

讲完了低版本操作,让我们继续回到这篇文章的主题——索引下推。

知道了痛点,那么怎么解决。很简单,只有符合条件了再进行回表。结合我们的例子来说就是当满足了性别 sex = 1 了,再回表查找。这样原本可能需要进行回表查找 4 次,现在可能只需要 2 次就可以了。

所以本质来说,索引下推就是只有符合条件再进行回表,对索引中包含的字段先进行判断,不符合条件的跳过。减少了不必要的回表操作。

总结

回表操作

  • 当所要查找的字段不在非主键索引树上时,需要通过叶子节点的主键值去主键索引上获取对应的行数据,这个过程称为回表操作。

索引下推

  • 索引下推主要是减少了不必要的回表操作。对于查找出来的数据,先过滤掉不符合条件的,其余的再去主键索引树上查找。

关于作者

作者:大家好,我是莱乌,BAT搬砖工一枚。从小公司进入大厂,一路走来收获良多,想将这些经验分享给有需要的人,因此创建了公众号【IT界农民工】。定时更新,希望能帮助到你。同时,我给大家肝了一份Redis面经手册,在我的公众号内回复【pdf】即可获取,希望对你有所帮助。

往期内容:

漫画系列:

漫画 | 程序员的悲哀是什么

入坑程序员,过来人给的一些小建议......

MySQL系列:

Mysql 中写操作时保驾护航的三兄弟!

面试官:Mysql 中主库跑太快,从库追不上怎么整?

MySQL中的这个池子,强的一批!

SQL:我为什么慢你心里没数吗?

Redis系列:

败家玩意儿!Redis 竟然浪费了这么多内存!

面试官:Redis 主从复制时网络开小差了怎么整?

同样是持久化,竟然有这么大的差别!

面试时说Redis是单线程的,被喷惨了!

硬核!15张图解Redis为什么这么快

缓存与库先写哪个,这十几张图告诉你!

Mysql:好好的索引,为什么要下推?的更多相关文章

  1. MySQL(五) MySQL中的索引详讲

    序言 之前写到MySQL对表的增删改查(查询最为重要)后,就感觉MySQL就差不多学完了,没有想继续学下去的心态了,原因可能是由于别人的影响,觉得对于MySQL来说,知道了一些复杂的查询,就够了,但是 ...

  2. Mysql几种索引类型的区别及适用情况

    如大家所知道的,Mysql目前主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RTREE. 那么,这几种索引有什么功能和性能上的不同呢? FULLTEXT 即为全文索引,目前只有MyI ...

  3. 数据库 MySQL进阶之索引

    数据库的索引非常重要,基本面试数据库的问题都在索引上,所以这里小编整理出来,一方面为了自己复习,一方面也方便大家. 一,索引前传 在了解数据库索引之前,首先有必要了解一下数据库索引的数据结构基础,那么 ...

  4. MySQL 进阶之索引

    一,索引前传 在了解数据库索引之前,首先有必要了解一下数据库索引的数据结构基础,那么什么样的数据结构可以作为索引呢? B-tree是最常用的用于索引的数据结构.因为它们是时间复杂度低, 查找.删除.插 ...

  5. BTREE这种Mysql默认的索引方式,具有普遍的适用性

    文章转自 https://blog.csdn.net/caomiao2006/article/details/52145477 Mysql目前主要有以下几种索引方式:FULLTEXT,HASH,BTR ...

  6. Mysql几种索引方式的区别及适用情况 (转)

    文章摘自http://blog.sina.com.cn/s/blog_4aca42510102v5l2.html Mysql目前主要有以下几种索引方式:FULLTEXT,HASH,BTREE,RTRE ...

  7. mysql强制使用索引

    在公司后台某模块功能记录日志中有一个搜索功能,通过前段时间的产品使用时间区间进行搜索反馈有些卡顿,我发现这个搜索功能比较慢,要3秒左右才能出来,就决定对这里做一下优化. 通过分析代码和SQL发现最核心 ...

  8. MySQL中的索引详讲

    一.什么是索引?为什么要建立索引? 索引用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的 ...

  9. MySQL建立高性能索引策略

    索引永远是最好的查询解决方案嘛? 索引并不总是最好的工具.总的来说,只有当索引帮助存储引擎快速查找到记录带来的好处大于其带来的额外工作(比如插入操作后索引的维护)时,索引才是高效的. 对于非常小的表: ...

  10. [转]Mysql几种索引类型的区别及适用情况

    此为转载文章,仅做记录使用,方便日后查看,原文链接:https://www.cnblogs.com/yuan-shuai/p/3225417.html Mysql几种索引类型的区别及适用情况   如大 ...

随机推荐

  1. HIve中 datediff,date_add和date_sub的用法

    1.日期比较函数:datediff语法:datediff(string enddate,string startdate) 返回值:int 说明:返回结束日期减去开始日期的天数. 例如: hive&g ...

  2. C# 设置默认关联程序

    以下代码做个Mark /// <summary> /// Create an associaten for a file extension in the windows registry ...

  3. 哎,这让人抠脑壳的 LFU。

    这是why哥的第 83 篇原创文章 让人抠脑壳的 LFU 前几天在某APP看到了这样的一个讨论: 看到一个有点意思的评论: LFU 是真的难,脑壳都给我抠疼了. 如果说 LRU 是 Easy 模式的话 ...

  4. 【C++】《C++ Primer 》第十五章

    第十五章 面向对象程序设计 一.OOP:概述 面向对象程序设计(OOP)的核心思想是数据抽象.继承和动态绑定. 通过使用数据抽象,可以将类的接口和实现分离. 使用继承,可以定义相似的类型并对其相似关系 ...

  5. LeetCode430 扁平化多级双向链表

    您将获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表.这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示. 扁平化列表,使所有结点 ...

  6. Deep Learn I'm back.

    Intorduction: 时隔好几个月,我准备重新进入Deep Learning 的领域.昨天和老师聊了很多,之前觉得我做的工作就是排列组合,在水论文,灌水.但老师却说:这也是为将来的研究打基础. ...

  7. Lniux 入门:03 用户及文件权限管理

    1.1 实验内容 Linux 中创建.删除用户,及用户组等操作. Linux 中的文件权限设置. 1.2 实验知识点 Linux 用户管理 Linux 权限管理 通过第一节课程的学习,你应该已经知道, ...

  8. 聊聊 g0

    很多时候,当我们跟着源码去理解某种事物时,基本上可以认为是以时间顺序展开,这是编年体的逻辑.还有另一种逻辑,纪传体,它以人物为中心编排史事,使得读者更聚焦于某个人物.以一种新的视角,把所有的事情串连起 ...

  9. Java 使用 commons-fileupload 实现文件上传工具类

    依赖包 文件上传可以使用 Apache 文件上传组件, commons-fileupload, 它依赖于 commons-io commons-io.jar: https://repo1.maven. ...

  10. 【Java】运算符(算术、赋值、比较(关系)、逻辑、条件、位运算符)

    运算符 文章目录 运算符 1. 算术运算符 2. 赋值运算符 3. 比较运算符 4. 逻辑运算符 5. 条件运算符 6. 位运算符 7. 运算符优先级 8. 运算符操作数类型说明 9.code 算术运 ...