什么是回表、索引覆盖、索引下推【重点】

news2024/11/21 2:39:42

参考链接
【1】https://xiaolincoding.com/mysql/index/index_interview.html#%E6%8C%89%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%88%86%E7%B1%BB
【2】https://www.toutiao.com/article/7095749260137726476/?wid=1709192807222
【3】https://zhuanlan.zhihu.com/p/401198674
【4】https://docs.pingcode.com/ask/39637.html
【5】https://blog.csdn.net/luxiaoruo/article/details/106637231

按照四个角度来分类索引。

  1. 按「数据结构」分类:B+tree索引、Hash索引、Full-text索引。
  2. 按「物理存储」分类:聚簇索引(主键索引)、二级索引(辅助索引)。
  3. 按「字段特性」分类:主键索引、唯一索引、普通索引、前缀索引。
  4. 按「字段个数」分类:单列索引、联合索引。

要知道什么是回表、索引覆盖、索引下推,首先大概理解B+树

B+树

主键索引:叶子节点中存储了全部元素的索引
二级索引:叶子节点中只存储了当前索引字段和主键ID

主键索引的 B+Tree

之前在讲MVCC时提到过,再次加深印象
InnoDB主键索引【聚簇索引】的叶子节点存储行记录,因此, InnoDB必须要有,且只有一个聚集索引:
(1)如果表定义了主键,则PK就是聚集索引;
(2)如果表没有定义主键,则第一个非空唯一索引(not NULL unique)列是聚集索引;
(3)否则,InnoDB会创建一个隐藏的row-id作为聚集索引;

如图所示(图中叶子节点之间实际上是双向链表):
补充:【B+Tree 相比于 B 树和二叉树来说,最大的优势在于查询效率很高,因为即使在数据量很大的情况,查询一个数据的磁盘 I/O 依然维持在 3-4次。】

在这里插入图片描述

============================================================================

主键索引的 B+Tree 和二级索引的 B+Tree 区别如下:

  1. 主键索引的 B+Tree 的叶子节点存放的是实际数据,所有完整的用户记录都存放在主键索引的 B+Tree 的叶子节点里
  2. 二级索引的 B+Tree 的叶子节点存放的是主键值,而不是实际数据。

二级索引的 B+Tree
(图中叶子节点之间实际上是双向链表)
在这里插入图片描述

大概理解的B+树的主键索引和二级索引,就比较好理解回表、索引覆盖和索引下推了

回表

在MySQL中,回表(Index Lookups)是指在 使用二级索引(Secondary Index)进行查询时,(没有得到想要的全部结果),就需要根据该索引的键值去主键索引(Primary Index)中查找对应的数据行的过程。

写一个会回表查询的SQL:
select id, name, age from index_opt_test where name=‘cc’ ;
解析:

​SQL需要查询的列包括 id、name、age、使用name='cc’二级索引,但是这时候只能得到 id 和 name的值,但是age不能通过这次索引获取到。这时候只能通过 id 主键索引 获取到整行数据之后再从结果中捞出来age列的数据,这个额外的通过主键索引查找数据的过程就是回表

回表操作可能导致额外的IO开销,影响查询性能,特别是当查询的列不包含在二级索引中。为了优化查询性能,可以使用覆盖索引(Covering Index)和索引下推(Index Condition Pushdown)技术来避免回表操作,提高查询效率。

索引覆盖。

当所有的列都能在二级索引树中查询到,就不需要再回表,这种情况就是索引覆盖。简单点来讲就是:所有不需要回表的查询操作都叫索引覆盖。

select id,name from user where name=‘shenjian’;
因为通过name='shenjian’就可以查询到id,name字段,无需回表,所以是索引覆盖。

实现索引覆盖:

  1. select id,name from user where name=‘shenjian’;

create table user (
id int primary key,
name varchar(20),
sex varchar(5),
index(name) 单列索引
)engine=innodb;

  1. 建立 联合索引
    select id,name,sex from user where name=‘shenjian’;

create table user1 (
id int primary key,
name varchar(20),
sex varchar(5),
index(name, sex) 联合索引,
)engine=innodb;

单列索升级为联合索引(name, sex)后,索引叶子节点存储了主键id,name,sex,都能够命中索引覆盖,无需回表。

下面这个查询SQL该怎么建联合索引?
select a from table where b = 1 and c = 2;
刚才在讲联合索引的时候已经说了这个知识点了,where条件有b和c的等值查询,联合索引就建成(b,c),由于select后面有a,我们就建立 (b,c,a) 的联合索引,并且可以用到覆盖索引,查询速度更快。

索引下推(ICP优化)

在需要进行 联合索引 的时候,使用ICP可以对联合索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少存储引擎访问基础表的次数和Server访问存储引擎的次数,(减少回表次数)。

ICP 适用的一个隐含前提是二级索引必须是联合索引、且在使用索引进行扫描时只能采用最左前缀匹配原则。组合索引后面的列出现在 where 条件里,因此可以先过滤索引元组、从而减少回表读的数量。

例子:
SQL语句:(联合索引)
select id, name, sex,age from user where name=‘cc’ and sex=‘male’ and age>20;

没有开启索引下推的过程如下:

  1. 数据库接收到查询请求后,解析查询语句,确定需要访问的数据表为"user"表。 Server层把name推到引擎层
  2. 存储引擎会扫描整个"user"表,根据“最左前缀原则”,引擎层根据二级索引name找到主键, 存储引擎将满足条件的数据行返回给Server层。(回表)
  3. Server层再根据sex、age筛选出最终的数据。
  4. 最后返回给客户端

开启了索引下推后的过程如下:

  1. 数据库接收到查询请求后,解析查询语句,并确定需要访问的数据表。Server层会将name=‘cc’、sex=‘male’ 和 age=20 下推到存储引擎
  2. 存储引擎根据下推的条件,利用姓名、性别和年龄字段的索引,直接定位到符合条件的数据行。
  3. 符合条件的数据行将被返回给Server层。(回表)
  4. Server层收到数据后,将数据返回给客户端。

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

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

相关文章

压缩式 交换式 碎片整理 :(使碎片减少或没有)

交换式碎片整理 首先流程 是 p3这个程序在运行,p1p2p4 的话在等待 ,然后p3这时要多用3个内存块,这是 p4 通过拷贝,将内存拷贝到磁盘上,对应的数据也是从主存中cp到磁盘此时主存多出3个内存块给p3继续使用 2.压缩式碎片…

请求响应与统一响应结果

1.请求响应 1.安装postman 2.简单的参数 //原始的请求参数的方法RequestMapping("/simoleParam")public String simpleParam(HttpServletRequest request){String name request.getParameter("name");String ageStr request.getParameter("age&quo…

android开发书籍推荐,android面试复习

笼统来说,中年程序员容易被淘汰的原因其实不外乎三点。 1、输出能力已到顶点。这个人奋斗十来年了,依旧碌碌无为,很明显这人的天花板就这样了,说白了,天赋就这样。 2、适应能力越来越差。年纪大,有家庭&…

【Java】基本数据类型、包装类与字符串间的转换 例题

写在前面: 关于这道题,初见感觉有点cpu烧坏了,准确来说是看了网上的一些讲解都感觉不尽人意。自己整理了一下,希望能帮助到大家。 题目: 如下两个题目输出结果相同吗?各是什么。 Object o1 true ? new…

【web APIs】5、(学习笔记)有案例!

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、js组成window对象定时器-延迟函数location对象navigator对象histroy对象 二 、本地存储(今日重点)localStorage(重点&am…

通过elementUI学习vue

<template><el-radio v-model"radio" label"1">备选项</el-radio><el-radio v-model"radio" label"2">备选项</el-radio> </template><script>export default {data () {return {radio: 1}…

[MYSQL数据库]--mysql的基础知识

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、数据库…

【力扣白嫖日记】550.游戏玩法分析IV

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 550.游戏玩法分析IV 表&#xff1a;Activity 列名类型player_idintdevice_idintevent_datedategames_played…

分享:大数据信用报告查询的价格一般要多少钱?

现在很多人都开始了解自己的大数据信用了&#xff0c;纷纷去查大数据信用报告&#xff0c;由于大数据信用与人行征信有本质的区别&#xff0c;查询方式和价格都不是固定的&#xff0c;本文就为大家详细讲讲大数据信用报告查询的价格一般要多少钱&#xff0c;希望对你有帮助。 大…

v69.字符

1.字符类型 1.1 可以将char类型的变量赋值为整数&#xff0c;也可以赋值为字符! 注意字符要用单引号 ’ ’ 而不是双引号 每一个字符在计算机内部都有一个值去表达它。字符’1’ 在计算机里表示的十进制的整数值为49&#xff0c;就像’A’表示十进制值65。 1.2 scanf 与 p…

人工智能_大模型011_CPU微调_训练_显卡的选型讲解_价格表_011---人工智能工作笔记0146

既然CPU训练大模型无法实现那么就只能购置GPU显卡来进行训练了,来看看如何选型显卡. 之前是没有GPU的,由于游戏行业对画质的需求,催生出了GPU,GPU优势是支持并行计算,可以几千个小核心同时计算,但是有个问题,如何把一个我们需要计算的问题,拆解成1000个或更多小问题,让GPU并行…

【C++】AVL树详解

目录 一、AVL树的概念 二、AVL树节点的定义 三、AVL树的操作 3.1 AVL树的平衡因子 3.2 AVL树的插入 3.3 AVL树的旋转 3.4 AVL树的验证 四、AVL树的完整代码 上一篇已经对关联式容器set/map/multiset/multimap进行了简答的介绍&#xff0c;大家可能发现它们有一个共同点&…

Tomcat服务部署

1、安装jdk、设置环境变量并测试 第一步&#xff1a;安装jdk 在部署 Tomcat 之前必须安装好 jdk&#xff0c;因为 jdk 是 Tomcat 运行的必要环境。 1. #关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 02. #将安装 Tomcat 所需软件包传到/opt…

在Windows中安装PyTorch

文章目录 1. 创建虚拟环境2. 检查显卡版本和CUDA3. 下载链接4. 下载5. 等待6. 检测 1. 创建虚拟环境 具体查看我之前写的 《在Windows中利用Python的venv和virtualenv创建虚拟环境》 2. 检查显卡版本和CUDA 这种情况是需要电脑上有单独的英伟达的显卡、或者英伟达的显卡和集显…

Retrofit核心原理

Retrofit是一个类型安全的HTTP客户端库&#xff0c;广泛用于Android和Java应用中&#xff0c;用于简化网络请求和响应的处理。本文将深入探讨Retrofit的核心原理&#xff0c;帮助开发者理解其背后的工作机制。 Retrofit简介 Retrofit是Square公司开发的一个开源库&#xff0c…

keepalived+HAProxy+MySQL双主实验

keepalivedHAProxyMySQL双主实验 环境准备 node1(HAProxy1):192.168.184.10 node2(HAProxy2):192.168.184.20 node3(MySQL1):192.168.184.30 node4(MySQL2):192.168.184.40 虚拟IP vip&#xff1a;192.168.184.100MySQL部署 在node3执行以下脚本&#xff1a; #!/bin/bash sy…

Linpmem:一款功能强大的Linux物理内存提取工具

关于Linpmem Linpmem是一款功能强大的Linux物理内存提取工具&#xff0c;该工具专为x64 Linux设计&#xff0c;可以帮助广大研究人员在执行安全分析过程中快速读取Linux物理内存数据。 该工具类似Windows下的Winpmem&#xff0c;Linpmem不是一个传统的内存转储工具&#xff0…

Leetcode—63. 不同路径 II【中等】

2024每日刷题&#xff08;115&#xff09; Leetcode—63. 不同路径 II 动态规划算法思想 实现代码 class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m obstacleGrid.size();int n obstacleGrid[0].size();…

【python】Python Turtle绘制流星雨动画效果【附源码】

在这篇技术博客中&#xff0c;我们将学习如何使用 Python 的 Turtle 模块绘制一个流星雨的动画效果。通过简单的代码实现&#xff0c;我们可以在画布上展现出流星闪耀的场景&#xff0c;为视觉带来一丝神秘与美感。 一、效果图&#xff1a; 二、准备工作 &#xff08;1)、导入…

Stable Diffusion中的Clip模型

基础介绍 Stable Diffusion 是一个文本到图像的生成模型&#xff0c;它能够根据用户输入的文本提示&#xff08;prompt&#xff09;生成相应的图像。在这个模型中&#xff0c;CLIP&#xff08;Contrastive Language-Image Pre-training&#xff09;模型扮演了一个关键的角色&a…