MySQL - 聚簇索引和非聚簇索引,回表查询,索引覆盖,索引下推,最左匹配原则

聚簇索引和非聚簇索引

聚簇索引和非聚簇索引是 InnoDB 里面的叫法

一张表它一定有聚簇索引,一张表只有一个聚簇索引在物理上也是连续存储的

它产生的过程如下:

  1. 表中有无有主键索引,如果有,则使用主键索引作为聚簇索引;
  2. 如果没有主键索引,则看表中有无唯一索引,那么使用第一个唯一索引;
  3. 如果以上两个条件都不满足,InnoDB 则会生成隐藏聚簇索引。

聚簇索引

聚簇索引一般是主键索引,

例如主键索引 id 对应的聚簇索引结构图(叶子节点存储整表数据):

 

非聚簇索引

非聚簇索引在 InnoDB 也叫做二级索引,非聚簇索引是普通列的索引(非主键索引)

例如普通 class_id 对应的非聚簇索引结构图(叶子节点存储的是聚簇索引):

 

MySQL的InnoDB索引数据结构是B+树

聚簇索引叶子结点存储的是行数据,而非聚簇索引叶子节点存储的是聚簇索引,因此通过聚簇索引可以找到真正的行数据;
由于非聚簇索引的叶子结点存储的是聚簇索引,因此使用非聚簇索引还需要进行回表查询,所以在查询效率方面,聚簇索引要高于非聚簇索引;
聚簇索引一般为主键索引,而一个表中只能有一个主键,因此一个表中也只能有一个聚簇索引,而非聚簇索引则没有数量上的限制。


 什么是回表查询 

由于非聚簇索引的叶子节点存储的不是真正的数据,而是聚簇索引,所以在使用普通索引进行查询操作时,会先查询到聚簇索引,然后再去聚簇索引对应的 B+ 数去查询真正的数据,这个过程就叫做回表查询。


例子

下面我们创建了一个学生表,做三种查询,来说明什么情况下是聚簇索引,什么情况下不是。

create table student (
    id bigint,
    no varchar(20) ,
    name varchar(20) ,
    address varchar(20) ,
    PRIMARY KEY (`branch_id`) USING BTREE,
    UNIQUE KEY `idx_no` (`no`) USING BTREE
)ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

第一种,直接根据主键查询获取所有字段数据,此时主键是聚簇索引,因为主键对应的索引叶子节点存储了id=1的所有字段的值。

select * from student where id = 1

第二种,根据编号查询编号和名称,编号本身是一个唯一索引,但查询的列包含了学生编号和学生名称,当命中编号索引时,该索引的节点的数据存储的是主键ID,需要根据主键ID重新查询一次,所以这种查询下no不是聚簇索引

select no,name from student where no = 'test'

第三种,我们根据编号查询编号(有人会问知道编号了还要查询?要,你可能需要验证该编号在数据库中是否存在),这种查询命中编号索引时,直接返回编号,因为所需要的数据就是该索引,不需要回表查询,这种场景下no是索引覆盖 

select no from student where no = 'test'

主键一定是聚簇索引,MySQL的InnoDB中一定有主键,即便研发人员不手动设置,则会使用unique索引,没有unique索引,则会使用数据库内部的一个行的id来当作主键索引,其它普通索引需要区分SQL场景,当SQL查询的列就是索引本身时,我们称这种场景下该普通索引也可以叫做聚簇索引,MyisAM引擎没有聚簇索引。


什么是索引覆盖

        索引覆盖是指在一个查询语句中,某个索引已经 "覆盖了" 需要被查询出来的列,此时就不需要进行回表查询了,这就叫做索引覆盖!!(索引覆盖它是非聚簇索引中的一个特殊情况)

当我们写了这样一个 SQL,实际上它走的是辅助索引,结构如下图:

select id from student where name = 'Bob';

  1. 辅助索引(非聚簇索引)中的查询,一般是需要查询两次,第一次查询出聚簇索引,然后根据聚簇索引回表查询,最终拿到行数据。
  2. 但是此处我的查询需求刚好就是聚簇索引,因此一次查询就可以拿到需要的列,不需要进行回表,这就是索引覆盖~

 以下四种情况都属于索引覆盖 >>

// 联合索引 (name,age)
select name from student where.....
 
select age from student where.....
 
select name,age from student where.....
 
select address,name,age from student where address = '深圳';

最后一个 SQL 因为 where 条件后面可以知道 address,所以也不需要回表查询!!


索引下推

索引下推是指在查询非聚簇索时,拿到了叶子结点的聚簇索引,然后对聚簇索引中包含的字段先做判断,直接过滤掉不满足条件的记录,从而减少回表次数,这就是索引下推!!(索引下推是在 MySQL 5.6 之后才引入的,它属于非聚簇索引中功能)

以 user 表中的联合索引(name,age)为例:

select * from user where name='张%' and age='10';
 
// 表中有四条数据
// 1  张三  10
// 2  张四  11
// 3  张五  12
// 4  老六  13

MySQL 5.6 之前没有索引下推,它的执行流程如下:

① 在非聚簇索引中根据 name='张%' 查到聚簇索引中匹配的 id

② 使用匹配的 id 进行回表查询

 此时会进行三次回表操作,而联合索引中的 age 字段就没用上。

MySQl 5.6 之后引入索引下推,它会根据 name='张%' 和 age 一起过滤数据:

【好处】:它的第二步操作就可以节省回表的次数

② 使用匹配的 id 进行回表查询

 引入索引下推后,只执行了一次回表查询,这就是索引下推的好处。


什么是最左匹配原则

  • 最左匹配原则是指索引以最左边的为起点,任何连续的索引都能匹配上,
  • 当遇到范围查询 (>、<、between、like) 就会停止匹配。

比如联合索引 index(a,b,c),以下 SQL 来理解什么是最左匹配原则:

select * from user where a=1; // 只使用索引 a
 
select * from user where b=2; // 不使用索引
 
select * from user where c=3; // 不使用索引
 
select * from user where a=1 and b=2; // 只使用索引 a,b
 
select * from user where a=1 and c=3; // 只是用索引 a
 
select * from user where b=2 and c=3; // 不使用索引
 
select * from user where a=1 and b=2 and c=3; // 使用索引 a,b,c
 
select * from user where a=1 and b like '%xxx' and c=3; // 只使用索引 a,b

【疑惑一】

        不是说使用了 like,就停止匹配了吗,为什么前面的索引下推使用了 name='张%' 还能再拿 age 进行过滤呢 ?

对于 like 查询,它的常见写法有三种:

模糊匹配后面任意字符:like '张%'
模糊匹配前面任意字符:like '%张'
模糊匹配前后任意字符:like '%张%'
        这三种情况,只有第一种情况是会走索引的,其他的都会导致索引失效,所以前面索引下推例子中的 name='张%' 是不会停止匹配的~

【疑惑二】

        当我们写出这样的条件语句 where a=1 and c=3 and b=2 时,引擎为什么不把它调整为 a,b,c 的顺序呢?

        MySQL 8.0 之后才涉及到这样的调优,但是具体会不会调优,是不一定的,因为索引调优的主动权在索引的优化器里面的,而优化器这个东西,它很玄学,所以不知道它会不会进行调优。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java - 线程间的通信方式

线程通信的方式 线程中通信是指多个线程之间通过某种机制进行协调和交互 线程通信主要可以分为三种方式&#xff0c;分别为共享内存、消息传递和管道流。每种方式有不同的方法来实现 共享内存&#xff1a;线程之间共享程序的公共状态&#xff0c;线程之间通过读-写内存中的公…

成都工业学院Web技术基础(WEB)实验六:ECMAScript基础语法

写在前面 1、基于2022级计算机大类实验指导书 2、代码仅提供参考&#xff0c;前端变化比较大&#xff0c;按照要求&#xff0c;只能做到像&#xff0c;不能做到一模一样 3、图片和文字仅为示例&#xff0c;需要自行替换 4、如果代码不满足你的要求&#xff0c;请寻求其他的…

吉祥物IP怎么结合动捕设备应用在线下活动?

一个好的吉祥物IP&#xff0c;不仅可以为品牌带来传播效果和形象具体化的价值&#xff0c;还可以带来一系列的商业利益。 当吉祥物IP接入惯性动作捕捉系统&#xff0c;即可由真人幕后穿戴动捕设备进行实时驱动&#xff0c;可以通过虚拟数字人直播、数字人短视频、数字人线下活动…

如何在Ubuntu的Linux系统上安装nacos的2.3.0版本

官方网址链接 home (nacos.io)Nacos 快速开始github代码仓库简单介绍 Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件&#xff0c;其可以用于服务发现和服务健康监测、动态配置服务、动态DNS服务、服务及其元数据管理。安装包下载地址&#xff1a; Releases …

Python3开发环境的搭建

1&#xff0c;电脑操作系统的确认 我的是win10、64位的&#xff0c;你们的操作系统可自寻得。 2&#xff0c;Python安装包的下载 &#xff08;1&#xff09;浏览器种输入网址&#xff1a;https://www.python.org 选择对应的系统&#xff08;我的是win10/64位) &#xf…

面试 JVM 八股文五问五答第一期

面试 JVM 八股文五问五答第一期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1.JVM内存布局 Heap (堆区&#xff09; 堆是 OOM 故障最主要的发生区域。它是内存…

CRM系统的这些功能助您高效管理客户

客户管理可以理解为企业收集并利用客户信息&#xff0c;满足客户的需求&#xff0c;从而提升客户价值的过程。CRM系统一直被誉为客户管理的“神器”&#xff0c;下面我们就来说说CRM系统有哪些功能可以管理客户&#xff1f; 1、客户信息管理 CRM可以帮助企业收集客户的基本信…

C++11(下)

可变参数模板 C11的新特性可变参数模板能够创建可以接受可变参数的函数模板和类模板. 相比C98/03, 类模版和函数模版中只能含固定数量的模版参数, 可变模版参数无疑是一个巨大的改进, 然而由于可变模版参数比较抽象, 使用起来需要一定的技巧, 所以这块还是比较晦涩的.掌握一些基…

《Spring Cloud Alibaba 从入门到实战》分布式配置

分布式配置 1、简介 Nacos 提供用于存储配置和其他元数据的 key/value 存储&#xff0c;为分布式系统中的外部化配置提供服务器端和客户端支持。 Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案&#xff0c;在特殊的 bootstrap 阶段&#xff0c;…

路灯控制系统中漏电保护怎么实施

应用场景1 应用于路灯配电箱的漏电检测 功能 可实时监测和显示路灯配电箱内多回路的剩余电流&#xff1b; 每只剩余电流监测仪最多可监测16个回路的剩余电流&#xff0c;剩余电流监测范围为1mA-30A&#xff1b; 每路剩余电流监测均可设置报警值&#xff0c;报警值的设置范围…

手机如何制作个人博客?安卓Termux+Hexo搭建博客网站并远程访问

文章目录 前言 1.安装 Hexo2.安装cpolar3.远程访问4.固定公网地址 前言 Hexo 是一个用 Nodejs 编写的快速、简洁且高效的博客框架。Hexo 使用 Markdown 解析文章&#xff0c;在几秒内&#xff0c;即可利用靓丽的主题生成静态网页。 下面介绍在Termux中安装个人hexo博客并结合…

Gateway全局异常处理及请求响应监控

前言 我们在上一篇文章基于压测进行Feign调优完成的服务间调用的性能调优&#xff0c;此时我们也关注到一个问题&#xff0c;如果我们统一从网关调用服务&#xff0c;但是网关因为某些原因报错或者没有找到服务怎么办呢&#xff1f; 如下所示&#xff0c;笔者通过网关调用acc…

dToF直方图之美_激光雷达多目标检测

直方图提供了一种简单有效的方法来分析信号分布并识别与目标存在相对应的峰值,并且能够可视化大量数据,让测距数形结合。在车载激光雷达中,对于多目标检测,多峰算法统计等,有着区别于摄像头以及其他雷达方案的天然优势。 如下图,当中有着清晰可见的三个峰值,我们可以非…

基于ssm的电动车租赁网站论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本电动车租赁网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

Draw.io or diagrams.net 使用方法

0 Preface/Foreword 在工作中&#xff0c;经常需要用到框图&#xff0c;流程图&#xff0c;时序图&#xff0c;等等&#xff0c;draw.io可以完成以上工作。 official website:draw.io 1 Usage 1.1 VS code插件 draw.io可以扩展到VS code工具中。

Java Web——过滤器 监听器

目录 1. Filter & 过滤器 1.1. 过滤器概述 1.2. 过滤器的使用 1.3. 过滤器生命周期 1.4. 过滤器链的使用 1.5. 注解方式配置过滤器 2. Listener & 监听器 2.1. 监听器概述 2.2. Java Web的监听器 2.2.1. 常用监听器 2.2.1.1. ServletContextListener监听器 …

SM4加密算法的侧信道攻击实现

SM4 算法有多个位置存在泄漏点&#xff0c;如下图所示&#xff1a; 在位置1和2&#xff0c;可以逐个字节攻击密钥&#xff0c;因为密钥和中间结果之间没有扩散&#xff0c;这时通常取Sbox的输出作为攻击点&#xff0c;因为在位置2处的功耗是大于位置1的&#xff0c;但是在FPGA…

ODOO领先其他ERP的王炸功能:作业路线!(含MTO模式配置图表)

和众多ERP系统比较&#xff0c;ODOO-ERP中的作业路线功能可谓相当强大&#xff0c;可以自行定义供应链路线&#xff0c;以及单据同步生成。极大地增强了不同业务场景的适应性和业务管理效率&#xff01; 自定义供应路线的特点&#xff1a;对于很多灵活多变的企业而言&#xff…

Java架构师系统架构实现高内聚低耦合

目录 1 导语2 边界内聚耦合概述3 聚焦内聚4 关注耦合5 如何实现高内聚低耦合6 内聚耦合规划不当的效果7 总结想学习架构师构建流程请跳转:Java架构师系统架构设计 1 导语 架构设计的核心维度,从系统的扩展性、高性能、高可用、高安全性和伸缩性五个维度进行了探讨,并介绍了…

JavaEE:计算机是如何工作的

JavaEE学什么&#xff1f; 主要学习Java开发网站后端&#xff0c;为后面学习Spring做铺垫 涉及的内容&#xff1a; 1&#xff09;操作系统基础知识 2&#xff09;多线程知识 3&#xff09;文件操作 4&#xff09;网络编程 5&#xff09;网络原理 6&#xff09;JVM 计算…