SQL - MySQL回表

news2024/11/16 7:55:08

一、回表概念;现象

回表,顾名思义就是回到表中,也就是先通过普通索引(我们自己建的索引不管是单列索引还是联合索引,都称为普通索引)扫描出数据所在的行,再通过行主键ID 取出索引中未包含的数据。所以回表的产生也是需要一定条件的,如果一次索引查询就能获得所有的select 记录就不需要回表,如果select 所需获得列中有其他的非索引列,就会发生回表动作。即基于非主键索引的查询需要多扫描一棵索引树。

Mysql回表指的是在InnoDB存储引擎下,二级索引查询到的索引列,如果需要查找所有列的数据,则需要到主键索引里面去取出数据。这个过程就称为回表。因为行的数据都是存在主键B+tree的叶子节点里面,二级索引的B+树叶子节点都是存放的(索引列,主键)

简单来说,回表就是 MySQL 要先查询到主键索引,然后再用主键索引定位到数据

回表现象

举个例子:

表tbl有a,b,c三个字段,其中 a是主键,b上建了索引,然后编写sql语句SELECT * FROM tbl WHERE a=1这样不会产生回表,因为所有的数据在a的索引树中均能找到

如果是SELECT * FROM tbl WHERE b=1这样就会产生回表,因为where条件是b字段,那么会去b的索引树里查找数据,但b的索引里面只有a,b两个字段的值,没有c,那么这个查询为了取到c字段,就要取出主键a的值,然后去a的索引树去找c字段的数据。查了两个索引树,就出现了回表操作

二、存储引擎;索引结构

要弄明白回表,首先得了解MySQL的存储引擎,以及默认存储引擎 InnoDB 的两大索引,即聚集索引 (clustered index)和 非聚簇索引/普通索引/二级索引/辅助索引(secondary index)

(一)存储引擎

MySQL中主要有2种存储引擎

1、MyISAM(不支持事物回滚)

MyIsam引擎是MySQL主流引擎之一,但它相比起InnoDB,没有提供对数据库事务的支持,不支持细粒度的锁(行锁)及外键,当表Insert与update时需要锁定整个表,因此效率会低一些,在高并发时可能会遇到瓶颈,但MyIsam引擎独立与操作系统,可以在windows及linux上使用。

可能的缺点:

不能在表损坏后恢复数据

适用场景:

1. MyIsam极度强调快速读取

2. MyIsam表中自动存储了表的行数,需要时直接获取即可

3. 适用于不需要事物支持、外键功能、及需要对整个表加锁的情形

2、InnoDB(支持事物回滚)

InnoDB是一个事务型存储引擎,提供了对数据库ACID事务的支持,并实现了SQL标准的四种隔离级别,具有行级锁定(这一点说明锁的粒度小,在写数据时,不需要锁住整个表,因此适用于高并发情形)及外键支持(所有数据库引擎中独一份,仅有它支持外键)

该引擎的设计目标便是处理大容量数据的数据库系统,MySQL在运行时InnoDB会在内存中建立缓冲池,用于缓存数据及索引。

可能的缺点:

1. 该引擎不支持FULLTEXT类型的索引

2. 没有保存表的行数,在执行select count(*) from 表名 时,需要遍历扫描全表

适用场景:

1. 经常需要更新的表,适合处理多重并发的更新请求

2. 支持事务

3. 外键约束

4. 可以从灾难中恢复(通过bin-log日志等)

5. 支持自动增加列属性auto_increment

show engines;

show engines; 查看mysql所支持的存储引擎,以及从中得到mysql默认的存储引擎 

可以看出,MySQL默认的数据库引擎是InnoDB

参数名称解释说明
Engine存储引擎名称
Support是否支持该引擎以及该引擎是否为默认存储引擎,YES表示支持,NO表示不支持
DEFAULTDEFAULT表示为默认存储引擎
Comment存储引擎的简单介绍
Transactions表示该引擎是否支持事务
XA说明该存储引擎是否支持分布事务
Savepoints说明该存储引擎是否支持部分事务回滚

(二)索引结构

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。可以得到索引的本质:索引是数据结构

MySQL默认的数据库引擎是InnoDB,InnoDB 存储引擎的两大索引,即聚集索引 (clustered index)和 非聚簇索引/普通索引/二级索引/辅助索引(secondary index)

1、聚集索引 (clustered index)

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

  • 如果表定义了主键,则Primary Key 就是聚集索引;
  • 如果表没有定义主键,则第一个非空唯一索引(Not NULL Unique)列是聚集索引
  • 否则,InnoDB会创建一个隐藏的row-id作为聚集索引

简单来说,聚簇索引是主键索引

2、非聚簇索引/普通索引/二级索引/辅助索引(secondary index)

主键索引之外的就是非聚簇索引,非聚簇索引又叫辅助索引或者二级索引

主键索引 和 非主键索引区别

相同点:都使用的是 B+Tree

不同点:叶子节点存储的数据不同

主键索引的叶子节点存储的是一行完整的数据

非主键索引的叶子节点存储的是主键值。叶子节点不包含记录的全部数据,非主键的叶子节点除了用来排序的 key 还包含一个书签(bookmark),其中存储了聚簇索引的 key

使用主键索引查询

# 主键索引的的叶子节点存储的是**一行完整的数据**,
# 所以只需搜索主键索引的 B+Tree 就可以轻松找到全部数据
select * from user where id = 1;

使用非主键索引查询

# 非主键索引的叶子节点存储的是**主键值**,
# 所以MySQL会先查询到 name 列的索引的 B+Tree,搜索得到对应的主键值
# 然后再去搜索该主键值查询主键索引的 B+Tree 才可以找到对应的数据
select * from user where name = 'Jack';

使用非主键索引要比主键索引多使用一次 B+Tree

二级索引查找的过程为先在二级索引找到主键索引的key,再在主键索引中查找(回表操作)

InnoDB表一定要建主键,并且最好使用int自增作为主键

这样做就是为了不用MySQL维护唯一列数据,节省资源。建立和维护索引过程中需要进行key的比较,int类型更好比较。自增使得树结构不容易产生树结构分裂,更节省算力

1、单值索引

即一个索引只包含单个列,一个表可以有多个单列索引

1

2

3

4

5

6

7

8

9

10

11

12

13

14

随表一起建索引:

CREATE TABLE customer (

id INT(10) UNSIGNED  AUTO_INCREMENT ,

customer_no VARCHAR(200),

customer_name VARCHAR(200),

PRIMARY KEY(id),

KEY (customer_name)

);

  

单独建单值索引:

CREATE  INDEX idx_customer_name ON customer(customer_name);

  

删除索引:

DROP INDEX idx_customer_name  on customer;

2、唯一索引

索引列的值必须唯一,但允许有空值

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

随表一起建索引:

CREATE TABLE customer (

id INT(10) UNSIGNED  AUTO_INCREMENT ,

customer_no VARCHAR(200),

customer_name VARCHAR(200),

  PRIMARY KEY(id),

  KEY (customer_name),

  UNIQUE (customer_no)

);

   

单独建唯一索引:

CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);

  

删除索引:

DROP INDEX idx_customer_no on customer ;

3、主键索引

设定为主键后数据库会自动建立索引,innodb为聚簇索引

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

随表一起建索引:

CREATE TABLE customer (

id INT(10) UNSIGNED  AUTO_INCREMENT ,

customer_no VARCHAR(200),

customer_name VARCHAR(200),

  PRIMARY KEY(id)

);

    

CREATE TABLE customer2 (

id INT(10) UNSIGNED   ,

customer_no VARCHAR(200),

customer_name VARCHAR(200),

  PRIMARY KEY(id)

);

  

 单独建主键索引:

ALTER TABLE customer

 add PRIMARY KEY customer(customer_no); 

  

删除建主键索引:

ALTER TABLE customer

 drop PRIMARY KEY

  

修改建主键索引:

必须先删除掉(drop)原索引,再新建(add)索引

4、复合索引

即一个索引包含多个列

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

随表一起建索引:

CREATE TABLE customer (

id INT(10) UNSIGNED  AUTO_INCREMENT ,

customer_no VARCHAR(200),

customer_name VARCHAR(200),

  PRIMARY KEY(id),

  KEY (customer_name),

  UNIQUE (customer_name),

  KEY (customer_no,customer_name)

);

  

单独建索引:

CREATE  INDEX idx_no_name ON customer(customer_no,customer_name);

  

删除索引:

DROP INDEX idx_no_name  on customer ;

(三)B-Tree 和 B+Tree

理解聚簇索引和非聚簇索引的关键在于 B+Tree 的理解

前者是 B-Tree,后者是 B+Tree,两者的区别在于:

  • B-Tree 中,所有节点都会带有指向具体记录的指针;B+Tree 中只有叶子结点会带有指向具体记录的指针。

  • B-Tree 中不同的叶子之间没有连在一起;B+Tree 中所有的叶子结点通过指针连接在一起。

  • B-Tree 中可能在非叶子结点就拿到了指向具体记录的指针,搜索效率不稳定;B+Tree 中,一定要到叶子结点中才可以获取到具体记录的指针,搜索效率稳定

基于上面两点分析,我们可以得出如下结论:

  • B+Tree 中,由于非叶子结点不带有指向具体记录的指针,所以非叶子结点中可以存储更多的索引项,这样就可以有效降低树的高度,进而提高搜索的效率。

  • B+Tree 中,叶子结点通过指针连接在一起,这样如果有范围扫描的需求,那么实现起来将非常容易,而对于 B-Tree,范围扫描则需要不停的在叶子结点和非叶子结点之间移动

三、索引创建场景

(一)需要创建索引

1、主键自动建立唯一索引

2、频繁作为查询条件的字段应该创建索引

3、查询中与其它表关联的字段,外键关系建立索引

4、单键/组合索引的选择问题, 组合索引性价比更高

5、查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度

6、查询中统计或者分组字段

(二)不要创建索引

1、表记录太少

2、经常增删改的表或者字段 原因:提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件

3、Where条件里用不到的字段不创建索引

4、过滤性不好的不适合建索引

四、覆盖索引避免回表

覆盖索引就是指索引中包含了查询中的所有字段,这种情况下就不需要再进行回表查询

一级索引:聚簇索引即主键索引
二级索引:非聚簇索引

一级B+Tree:叶子节点保存着键(id的值)和数据(全部字段的值)
二级B+Tree:叶子节点保存着键(索引字段的值)和数据(主键索引值)

查询 一级索引,根据一级B+Tree查询到数据,直接返回数据
查询 二级索引,根据二级B+Tree查询到对应的聚簇索引,再根据聚簇索引在一级B+Tree里查询到相应数据

查询 一级索引只需要扫描一次B+Tree。
查询 二级索引需要扫描两次B+Tree。根据二级B+Tree扫描的结果,再去一级B+Tree里进行扫描就叫回表操作

如果使用组合索引,就可以利用覆盖索引避免回表操作

例:表一共有五个字段:a(主键索引),b_c_d(组合索引),e(没有索引)

如果用户查询时只查 b,c,d;SELECT `b`, `c`, `d` FROM `table` WHERE `b` = 3 AND `c` = 7 AND `d` = 5;

因为查询的字段 b,c,d的值(B+Tree里的键) 已经在B+Tree里了,所以就可以直接返回,不用再拿聚簇索引去一级B+Tree里进行查询

如果查询字段为 a,b,c,d,因为a为主键索引,也保存在二级B+Tree的叶子节点里,所以也不用回表查询

【a是主键,给bcd建立联合索引】,如上几个sql,select出来的内容,和where条件字段,刚好和建立的索引一致

如果查询字段为 a,b,c,d,e,因为e没有在这个二级B+Tree里,所以需要进行回表操作,拿着主键索引再去一级B+Tree里进行查询

使用覆盖索引,我们需要select出来的列,都已经存在了索引树的叶子节点上。所以不需要回表操作,如果我们select出来的某列,不在该联合索引的叶子节点上(比如上表的e列),那就需要根据对应索引值,去聚簇索引树上回表查询对应的e列值了

参考链接

MySQL 回表 - 涛姐涛哥 - 博客园

什么是MySQL的回表?_一年春又来的博客-CSDN博客_回表

MySQL 存储引擎 - 知乎

https://www.jb51.net/article/239235.htm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/98442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]计算机毕业设计Python创新创业管理系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等…

Trie(Trie字符串统计)【实质就是二维数组 表示 链表】【二维数组的第一行就是 头结点】

欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示:重难点✔ 蓝色文字表示&#xff1a…

探索MapReduce

文章目录一,案例分析(一)TopN分析法介绍(二)案例需求二,案例实施(一)准备数据文件(1)启动hadoop服务(2)在虚拟机上创建文本文件&#…

ArcGIS中的OBJECTID、FID 和 OID 的区别!不要傻傻分不清

喜欢就关注我们吧 时常有很多我朋友分不清OBJECTID、FID 和 OID有什么区别,不懂得怎么应用和管理,今天我们来说个明白。 ArcGIS Desktop 产品要求独立表和属性表均具有 ObjectID字段,该字段包含唯一的长整型用于标识每个记录。 此 ID 由 Esri…

第二证券|元宇宙发展规划出炉,3只元宇宙概念股估值创年内新低

本月以来,北上资金加仓23只元国际概念股。 12月15日晚间,浙江省发改委等5部门联合印发《浙江省元国际工业开展举动计划(2023—2025年)》(以下简称《计划》)。《计划》中说到,到2025年&#xff0…

查找外文文献必备网站

查找下载外文文献不仅先要找到文献数据库资源,并且还需要有数据库的文献下载权限,如果你没有文献数据库使用权限就用下面这个方法。 文献党下载器(wxdown.org)有资源有权限,覆盖全科。下面举几个例子,用文…

脑电图分类任务中深度神经网络模型的数据增强:综述2021

Data Augmentation for Deep Neural Networks Model in EEG Classification Task: A Review 脑电图(EEG)的分类是测量神经活动节奏振荡的关键方法,是脑机接口系统(BCI)的核心技术之一。然而,从非线性和非平…

RNA-seq 详细教程:似然比检验(13)

学习内容 应用似然比检验 (LRT) 进行假设检验将 LRT 生成的结果与使用 Wald 检验获得的结果进行比较从 LRT 显著基因列表中识别共享表达谱似然比检验 在评估超过两个水平的表达变化时,DESeq2 还提供似然比检验作为替代方法。被确定为重要的基因是那些在不同因子水平…

Vue基础6

Vue基础6收集表单数据过滤器局部过滤器全局过滤器内置指令v-textv-html使用安全性cookie工作原理v-html不安全案例v-cloak指令v-once指令v-pre指令自定义指令函数式对象式自定义命名组合式全局自定义指令自定义指令总结&#xff1a;收集表单数据 <!DOCTYPE html> <ht…

VMware、linux虚拟机设置网络实现虚拟机与主机网络互通

需要配置三个方面才可以&#xff0c;即&#xff1a;WMware网络配置、windows主机网络配置、虚拟机网络配置。 首先&#xff0c;确认VMware虚拟机设置中配置的网络连接方式为&#xff1a;NAT模式 可以在VMware上方的菜单中找到&#xff1a;虚拟机---->设置&#xff0c;然后…

HC-SR04超声波测距模块介绍

超声波简介 超声波是由机械振动产生的, 可在不同介质中以不同的速度传播, 具有定向性好、能量集中、传输过程中衰减较小、反射能力较强等优点。超声波传感器可广泛应用于非接触式检测方法,它不受光线、被测物颜色等影响, 对恶劣的工作环境具有一定的适应能力, 因此在水文液位测…

毕业设计 - 基于JSP_Servlet校园二手交易平台设计于实现【源码+论文】

文章目录前言一、项目设计1. 模块设计2. 实现效果二、部分源码项目源码前言 今天学长向大家分享一个 java web 设计项目: 基于JSP/Servlet校园二手交易平台设计于实现 一、项目设计 1. 模块设计 系统完成的主要功能有&#xff1a;用户设置功能、发布信息功能、信息管理功能…

Android中AP和BP概念

AP和BP 大多数的手机都含有两个处理器。操作系统、用户界面和应用程序都在Application Processor(AP)上执行&#xff0c;AP一般采用ARM芯片的CPU。而手机射频通讯控制软件&#xff0c;则运行在另一个分开的CPU上&#xff0c;这个CPU称为Baseband Processor(BP)。 把射频功能放…

《API安全技术与实战》 读书笔记 API的前生今世和API安全的演进

文章目录一、API的前生今世&#xff08;1&#xff09;4中API表现形式&#xff08;2&#xff09;基于技术形式的类型划分的API二、API安全的演进&#xff08;1&#xff09;什么是API安全&#xff08;2&#xff09;常见的API安全漏洞类型一、API的前生今世 &#xff08;1&#x…

Nacos系列——Nacos概述(2.x版本)1-1

Nacos系列——Nacos概述&#xff08;2.x版本&#xff09;1-1前言Nacos概述&#xff08;2.x版本&#xff09;文档地址关键特性服务发现和服务健康监测动态配置服务动态 DNS 服务服务及其元数据管理Nacos地图核心概念地域可用区接入点命名空间配置配置管理配置项配置集配置集 ID配…

[阶段4 企业开发进阶] 7. 微服务

文章目录1 微服务1.1 微服务概念1.2 SpringCloud1.3 工程搭建1.4 支付模块构建cloud-provider-payment-80011 微服务 1.1 微服务概念 概念 Microservice architectures are the ‘new normal’. Building small, self-contained, ready to run applications can bring great f…

毕业设计 Stm32家庭气象仪 天气监控系统 - 物联网 单片机 嵌入式

文章目录0 前言1 简介2 主要器件3 实现效果4 设计原理4.1 DHT11温湿度传感器4.2 MQ135空气质量传感器4.35 部分核心代码6 最后0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩…

安全分析模型自动化调优

安全分析模型自动化调优 MLOps&#xff08;Machine Learning Operations&#xff09;是一种人工智能 的工程实践&#xff0c;是面向机器学习项目的研发运营管理体系 。旨在实现 ML 管道的操作、ML 模型的部署和管理标准化&#xff0c;支持ML 模型的发布、激活、监控、性能跟踪…

Stm32旧版库函数18——读传感器

/******************************************************************************* // // 使用单片机STM32F100C8T6 // 晶振&#xff1a;8.00M // 编译环境 Keil uVision4 // 在3.3V的供电环境下&#xff0c;就能运行 // 波特率 19200 ************************************…

SpringBoot请求参数传递与接收

一、GET请求和POST请求的区别是什么 GET和POST请求的区别主要有下面几点 GET没有请求体&#xff0c;POST有请求体GET传输比POST快GET只能携带少量数据&#xff08;因为其请求url有长度限制&#xff09;&#xff0c;POST可以携带的数据量较大POST因为将数据放在请求体中&#…