一文弄懂什么是MySQL的回表

 更新时间:2023年06月06日 10:16:20   作者:逆流°只是风景-bjhxcc  
本文主要介绍了一文弄懂什么是MySQL的回表,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、背景

先要从 InnoDB 的索引实现说起,InnoDB 有两大类索引:

  • 聚集索引 (clustered index)
  • 普通索引 (secondary index)

InnoDB 聚集索引和普通索引有什么差异?

InnoDB 普通索引 的叶子节点存储主键值。

注意:只有 InnoDB 普通索引才存储主键值,MyISAM 的二级索引都是直接指向数据块的。

InnoDB 聚集索引 的叶子节点存储行记录,因此,InnoDB 必须要有,且只有一个聚集索引:

如果表定义了主键,则主键就是聚集索引;

如果表没有定义主键,则第一个 not null 的 unique 列是聚集索引;

否则,InnoDB 会创建一个隐藏的 row-id 作为聚集索引;

注意:所以主键查询非常快,直接定位行记录。

二、什么是回表查询?

通俗的讲就是,如果索引的列在 select 所需获得的列中(因为在 mysql 中索引是根据索引列的值进行排序的,所以索引节点中存在该列中的部分值)或者根据一次索引查询就能获得记录就不需要回表,如果 select 所需获得列中有大量的非索引列,索引就需要到表中找到相应的列的信息,这就叫回表。

InnoDB聚集索引的叶子节点存储行记录,因此, InnoDB必须要有,且只有一个聚集索引:

(1)如果表定义了主键,则PK就是聚集索引;
(2)如果表没有定义主键,则第一个非空唯一索引(not NULL unique)列是聚集索引;
(3)否则,InnoDB会创建一个隐藏的row-id作为聚集索引;

三、可以举一个简单的例子

我有一张用于用户登录的user表:

字段名类型说明
idbigint(20)主键ID
usernamevarchar(20)用户名
passwordvarchar(20)密码

假如现在有一个用户名为admin,密码为123的用户要登录,那我会先找出username为admin的那条用户数据

SELECT * FROM user WHERE username = 'admin'

再根据查出来的user信息去对比密码是否正确

这时你发现username字段是唯一的又经常作为where条件所以可以给username字段建一个索引,于是就给username建了一个普通的B+Tree索引。

这时候就出问题的,因为MySQL的InnoDB使用聚簇索引,具体的数据只和主键索引放在一起,其他的索引只存储了数据的地址(主键id)。

比如上面的例子中,我根据username索引找到的只是一个username为admin这条数据的id而不是这条数据信息,所以要找到整条数据信息要根据得到的id再去找。

看完上面的流程,你应该已经发现问题了,我要通过username找到id,再根据id找整条数据,这里有两个查找过程,这是影响效率的。就像上面的两个查找过程就是回表了。

四、解决办法

使用覆盖索引可以解决上面所说的回表的问题。
还是拿上面上面登录的例子来说,其实登录只需要判断用户名和密码,如果user表中有其他用户信息也是不需要的那我们能不能只查询一次就找到这个用户名对应的密码呢。

这个是可以的,上面所说的分两步查找,第一步根据username查找是肯定不能少的,那我们只要把password和索引username放到一起就可以了。我们可以建立一个(username、password)的组合索引,这里username一定要放在前面,然后我们把sql语句改一下

SELECT username, password FROM user WHERE username = 'admin'

SELECT password FROM user WHERE username = 'admin'

这样建立组合索引后根据username查找password,只要一步查找就可以查找到,因为password已经是username索引的一部分了,直接可以查出来,不再需要通过id找对应的整条数据。覆盖索引就是覆盖了多个列(字段)的索引。

五、更多如下图:

(1)先通过普通索引定位到主键值id=5;
(2)在通过聚集索引定位到行记录;

这就是所谓的回表查询,先定位主键值,再定位行记录,它的性能较扫一遍索引树更低。

六、总结

使用聚集索引(主键或第一个唯一索引)就不会回表,普通索引就会回表。

到此这篇关于一文弄懂什么是MySQL的回表的文章就介绍到这了,更多相关MySQL 回表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL慢查询日志的作用和开启

    MySQL慢查询日志的作用和开启

    这篇文章主要给大家介绍了关于MySQL慢查询日志的作用和开启的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • explain分析sql效率的方法

    explain分析sql效率的方法

    下面小编就为大家带来一篇explain分析sql效率的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 如何修改mysql数据表主键

    如何修改mysql数据表主键

    这篇文章主要介绍了如何修改mysql数据表主键问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 详解MySQL用事件调度器Event Scheduler创建定时任务

    详解MySQL用事件调度器Event Scheduler创建定时任务

    事件调度器(Event Scheduler)是在MySQLv5.1.6中新增的一个功能,它相当于一个定时器,可以在指定的时间点执行一条SQL语句或一个语句块,也可以用于在固定间隔重复执行。下面跟着小编一起来学习学习在MySQL中如何用事件调度器Event Scheduler创建定时任务
    2016-08-08
  • Mongodb中关于GUID的显示问题详析

    Mongodb中关于GUID的显示问题详析

    这篇文章主要给大家介绍了关于Mongodb中GUID的显示问题,文中通过示例代码介绍的非常详细,对大家学习或者使用Mongodb具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-05-05
  • MySQL内部函数的超详细介绍

    MySQL内部函数的超详细介绍

    众所周知MySQL有很多内置的函数,下面这篇文章主要给大家介绍了关于MySQL内部函数的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-08-08
  • CentOS7 64位下MySQL5.7安装与配置教程

    CentOS7 64位下MySQL5.7安装与配置教程

    这篇文章主要介绍了CentOS7 64位下MySQL5.7安装与配置教程,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • Mysql 索引结构直观图解介绍

    Mysql 索引结构直观图解介绍

    Mysql-索引结构直观图解。上一篇刚刚通俗化的说明了B-TREE的几个结果与存储方式,其实跟索引感觉上还是没有关联起来, 那么本篇,就通过实际的一个数据行的例子,说明一下
    2016-12-12
  • Centos5.5中安装Mysql5.5过程分享

    Centos5.5中安装Mysql5.5过程分享

    这篇文章主要介绍了Centos5.5中安装Mysql5.5过程分享,本文使用编译方法安装MySQL,并给出了一些可能遇到的错误和解决方法,需要的朋友可以参考下
    2015-01-01
  • mysql 开启慢查询 如何打开mysql的慢查询日志记录

    mysql 开启慢查询 如何打开mysql的慢查询日志记录

    mysql慢查询日志对于跟踪有问题的查询非常有用,可以分析出当前程序里有很耗费资源的sql语句,那如何打开mysql的慢查询日志记录呢,接下来将详细为您介绍
    2012-11-11

最新评论