当前位置: 首页 > news >正文

MySQL-6、单表访问方法

 前言

前面介绍了MySQL表空间相关的内容。包括区、段、碎片区,还有一些不同的页类型的作用。

(如果没有看前面五篇文章,不建议看此篇文章)

  传送门:

MySQL-1、InnoDB行格式

MySQL-2、InnoDB数据页

MySQL-3、索引

MySQL-4、B+树索引的使用

MySQL-5、InnoDB的表空间

访问方法的概念

我们平时写的最多的就是查询语句,本质上是一种声明式的语法,是MySQL规定的语法。同一个查询语句可以使用多种不同的访问方法来执行,虽然最后的结果是一样的,但是不同的执行方式,所耗费的时间成本差距是很大的。

MySQL把执行查询语句的方式称为访问方法或者访问类型

const

const翻译过来就是常量,意思就是常量级别的访问方法 。

通过主键或者唯一二级索引列来定位一条记录的访问方法就是const级别(常量级别代价是可以忽略不计的)。不过这种访问方法只能在主键或唯一二级索引列与一个值进行等值比较才有效。因为采用等值查询,才可以保证最多只有一条记录符合搜索条件。

由于唯一二级索引列不限制NULL值的数量,当进行NULL查询时,就可能访问到多条记录,也就不会常采用const级别。

ref

通过二级索引列进行等值比较,形成的单点扫描区间,这种查询的访问方法称为ref。

这里再啰嗦以下,采用二级索引来执行查询操作时,每获取一条二级索引记录,就会立刻对其执行回表操作,而不是将所有二级索引记录的主键值都收集起来之后再统一执行回表操作。(这里说的回表的前提是,要查询的字段数据,在聚簇索引里才有)

使用二级索引查询,还有两点情况:

  • 二级索引列允许为NULL时,无论是普通二级索引,还是唯一二级索引。在执行 二级索引列 IS NULL查询时,最多只能使用ref访问方法。
  • 如果是联合索引(也是二级索引),只要最左边连续的列进行等值比较,就可以才用ref访问方法。如果最左边的列不全是等值比较的话,那就不能用ref。

ref_or_null

ref_or_null从名字上看,就是在ref的基础上,再判断为NULL的情况。实际上也就是这样。

通过二级索引列进行等值比较,形成的单点扫描区间,同时还有 OR 二级索引列 IS NULL的条件,这种查询的访问方法称为ref_or_null。形成的扫描区间就是 ['值','值']和[NULL,NULL]。

ref_or_null访问方法只是比ref访问方法多扫描了一些值为NULL的二级索引记录。

值为NULL的记录会被放在索引的最左边

range

range从名字上也可以看出,是范围级别。通过使用索引执行查询时,对应的扫描区间为若干个单点扫描区间或者范围是范围扫描区间,这种访问方法 称为 range。

这种扫描区间不能叫做 range,那就是(-∞,+∞),这种是全部扫描。zong

index

查询的列和筛选条件都是索引列,不需要回表,称为index。也称为索引覆盖。

all

all没有什么可说的,就是全表扫描。

索引合并

一般情况下,MySQL执行一条sql,只会为单个索引生成扫描区间,但是也有一些特殊情况。在这些特殊情况下,MySQL会为多个索引生成扫描区间。MySQL把这种使用多个索引来完成一次查询 的执行方法称为 索引合并(index merge)。共有3种特殊情况,说特殊情况前,先把之前的表结构搬过来。

create table demo_table
(id int not null auto_increment,key1 varchar(50),key2 int,key3 varchar(100),key_part1 varchar(100),key_part2 varchar(100),key_part3 varchar(100),des varchar(255),primary key(id),key idx_key(key1),unique key uk_key2(key2),key idx_key3(key3),key idx_key_part(key_part1,key_part2,key_part3)
)

该表iid为自增长主键,key1和key3为普通索引,key2为唯一索引,key_part1,key_part2,key_part3为联合索引。

1.Intersection 索引合并

现在有下面一条sql:

select * from demo_table where key1 = 'a' and key3 = 'c';

了解之前B+树使用的文章知道,会有三种执行方式来减少扫描数据。

  • 第一种,全表扫描。。(有索引,这肯定不用)
  • 第二种 ,使用key1的二级索引,对应的扫描区间就是[a,a]。然后每获取一条二级索引记录,回表查询其他字段数据。最后再判断key3 是否等于 c,依次循环。直到找到第一条不符合key1 = 'a'的数据为止。
  • 第三种,使用key3的二级索引,对应的扫描区间就是[b,b]。然后每获取一条二级索引记录,回表查询其他字段数据。最后再判断key1 是否等于 a,依次循环。直到找到第一条不符合key3 = 'c'的数据为止。

其实还有一种可能,之前我们说过,二级索引会根据列值进行排序,如果列值相同,会根据主键值再排序。上面的sql就符合这种条件。

  • 第四种,同时使用key1的二级索引和key3的二级索引。key1索引的扫描区间是[a,a],key3的扫描区间是[b,b],然后在两者的操作结果中找出主键值相同的记录(就是共有的主键值)。然后根据共有的主键值回表,去聚簇索引中查找完整记录。

使用Intersection 索引合并有个必要条件,从使用的每个索引中获取到的二级索引记录都是按照主键值排序的。为什么要有这个必要条件呢,主要从以下两点:

  • 从两个有序的集合中取交集比从两个无序的集合中取交集要容易的多。
  • 如果获取到的主键值是有序的,则根据主键值进行回表时就不再是进行单纯的随机I/O,从而提高效率。

下面大致说下第四种方式的执行过程:

  • 假设key1的扫描区间[a,a],其中主键值是 2,6,9,假设key3的扫描区间[b,b],对应的主键值是 3,6,15。
  • 先从key1的扫描区间取出第一条记录,该记录主键值为1。然后从key3的扫描区间取出一条记录,该记录主键值为3。因为 2 <  3,所以直接丢弃key1中取出的第一条记录。
  • 接着继续从key1的扫描区间取出第二条记录,该记录主键值为5。然后根据上一步骤中key3的扫描区间取出第一条记录进行比较,该记录主键值为3。因为 6 > 3,所以直接丢弃key3中取出的第一条记录。
  • 接着从key3的扫描区间取出第二条记录,该记录主键值为6。然后根据上一步骤中key1的扫描区间取出第二条记录。因为 6 = 6,也就意味着取交集成功,然后进行回表,将回表获取到的完整数据发送给客户端。(这个客户端不是真正的我们用户,而是MySQL的程序,最后将所有符合的数据,一起返回给用户)
  • 同理依次执行上面的步骤,直到将所有扫描区间遍历完毕。

下面看下不能用Intersection 索引合并的sql

select * from demo_table where key1 = 'a' and key_part1 = 'b';

key1的二级索引记录是按照主键值排序的,但是key_part1是聚合索引,显示按照key_part1排序,然后按照key_part排序,然后按照key_part3排序。key_part1的扫描区间中的主键值不是有序的。

2.Union索引合并

Intersection 索引合并就是把相同的主键值取交集。有交集就有并集,Union索引合并就是取并集。同理我们看下面的sql

select * from demo_table where key1 = 'a' or key3 = 'b';

参照上面Intersection 索引合并,上面sql也有三种执行方案。分别是使用key1二级索引、key3二级索引、全表扫描。当然也有第四种,那就是Union索引合并方案。

可以同时使用key1二级索引和key3二级索引来执行查询,在key1二级索引的扫描区间[a,a],在key3二级索引的扫描区间[b,b]。然后根据两个记录主键值的集合去重,最后根据去重后的主键值集合回表,这样重复的主键值只会回表一次。

同理使用Union索引合并也有一个必要条件:从使用的每个索引中获取到的二级索引记录都是按照主键值排序的。原因同上。

3.Sort-Union索引合并

上面两种索引合并的前提条件都是二级索引下的主键值,必须是有序的。Sort-Union索引合并就是解决如果是无序的一种情况,我们看下面的sql

select * from demo_table where key1 > 'a' or key3 < 'y';

这种情况,二级索引下的主键值肯定是无序的。但是我们又想使用索引合并,那该怎么办呢?这就用到了Sort-Union,看字面意思,就是排序+合并。真是的也是这样的,先将key1二级索引和key3二级索引查出来后,分别对查询的主键值进行排序,然后将两个主键值集合进行合并。最后是回表操作。所以与Union索引合并的区别就是,合并前,会进行一次排序操作。

不知道大家会不会有个疑问,为什么没有Sort-Intersection??

原因如下:

  • Union 的目标是合并结果集,所以排序后的合并是有效的优化。
  • Intersection 的目标是找到结果集的共同元素,重点在于匹配,而不是合并顺序。因为排序好了之后还是会继续检索后面的数据是否有交集。Intersection 索引合并有序是为了在回表的时候减少随机I/O。

总结:

MySQL的访问方法,根据性能排序:const > ref > ref_or_null > range > index > all。

我们怎么知道这条sql的执行方法是const、ref、range、index、还是全表扫描呢。又怎么知道这条sql用到了索引合并,用到的具体是哪种索引合并呢。在后面会具体写一篇关于MySQL EXPLAIN用法的文章,后面再做介绍。

相关文章:

MySQL-6、单表访问方法

前言 前面介绍了MySQL表空间相关的内容。包括区、段、碎片区&#xff0c;还有一些不同的页类型的作用。 &#xff08;如果没有看前面五篇文章&#xff0c;不建议看此篇文章&#xff09; 传送门&#xff1a; MySQL-1、InnoDB行格式 MySQL-2、InnoDB数据页 MySQL-3、索引 M…...

C语言实现三角波生成

C语言实现三角波生成 #include <stdio.h>#define SAMPLE_RATE 10000 // 采样率10kHz=10000Hz 对应100us=0.1ms #define UP_TIME 12.5 //上升时间12.5ms #...

WPF国际化的最佳实践

WPF国际化的最佳实践 1.创建项目资源文件 如果你的项目没有Properties文件夹和Resources.resx文件&#xff0c;可以通过右键项目-资源-常规-添加创建或打开程序集资源 2.添加国际化字符串 打开Resources.resx文件&#xff0c;添加需要翻译的文本字符&#xff0c;并将访问修…...

ctfshow web

【nl】难了 <?php show_source(__FILE__); error_reporting(0); if(strlen($_GET[1])<4){echo shell_exec($_GET[1]); } else{echo "hack!!!"; } ?> //by Firebasky //by Firebasky ?1>nl //先写个文件 ?1*>b //这样子会把所有文件名写在b里…...

【力扣】矩阵中的最长递增路径

一、题目描述 二、解题思路 1、先求出以矩阵中的每个单元格为起点的最长递增路径 题目中说&#xff0c;对于每个单元格&#xff0c;你可以往上&#xff0c;下&#xff0c;左&#xff0c;右四个方向移动。那么以一个单元格为起点的最长递增路径就是&#xff1a;从该单元格往上…...

语音深度鉴伪识别项目实战:基于深度学习的语音深度鉴伪识别算法模型(二)音频数据预处理及去噪算法+Python源码应用

前言 深度学习技术在当今技术市场上面尚有余力和开发空间的&#xff0c;主流落地领域主要有&#xff1a;视觉&#xff0c;听觉&#xff0c;AIGC这三大板块。 目前视觉板块的框架和主流技术在我上一篇基于Yolov7-LPRNet的动态车牌目标识别算法模型已有较为详细的解说。与AIGC相…...

网络原理——http/https ---http(1)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 网络原理 HTTP/HTTPS HTTP,全称为"超文本传输协议" HTTP 诞⽣与1991年. ⽬前已经发展为最主流使⽤的⼀种应⽤层协议. 实际上,HTTP最新已经发展到 3.0 但是当前行业中主要使用的HT…...

Docker安装、使用,容器化部署springboot项目

目录 一、使用官方安装脚本自动安装 二、Docker离线安装 1. 下载安装包 2. 解压 3.创建docker.service文件 4. 启动docker 三、docker常用命令 1. docker常用命令 2. docker镜像命令 3. docker镜像下载 4.docker镜像push到仓库 5. docker操作容器 6.docker …...

USB主机模式——Android

理论 摘自&#xff1a;USB 主机和配件概览 | Connectivity | Android Developers (google.cn) Android 通过 USB 配件和 USB 主机两种模式支持各种 USB 外围设备和 Android USB 配件&#xff08;实现 Android 配件协议的硬件&#xff09;。 在 USB 主机模式下&#xff0…...

240520Scala笔记

240520Scala笔记 第 7 章 集合 7.1 集合1 数组Array 集合(Test01_ImmutableArray): package chapter07 ​ object Test01_ImmutableArray {def main(args: Array[String]): Unit {// 1. 创建数组val arr: Array[Int] new Array[Int](5)// 另一种创建方式val arr2 Array(…...

【React】封装一个好用方便的消息框(Hooks Bootstrap 实践)

引言 以 Bootstrap 为例&#xff0c;使用模态框编写一个简单的消息框&#xff1a; import { useState } from "react"; import { Modal } from "react-bootstrap"; import Button from "react-bootstrap/Button"; import bootstrap/dist/css/b…...

tomcat10部署踩坑记录-公网IP和服务器系统IP搞混

1. 服务器基本条件 使用的阿里云服务器&#xff0c;镜像系统是Ubuntu16.04java version “17.0.11” 2024-04-16 LTS装的是tomcat10.1.24阿里云服务器安全组放行了&#xff1a;8080端口 服务器防火墙关闭&#xff1a; 监听情况和下图一样&#xff1a; tomcat正常启动&#xff…...

探索Sass:Web开发的强大工具

在现代Web开发中,CSS(层叠样式表)作为前端样式设计的核心技术,已经发展得非常成熟。然而,随着Web应用的复杂性不断增加,传统的CSS书写方式逐渐暴露出一些不足之处,如代码冗长、难以维护、缺乏编程功能等。为了解决这些问题,Sass(Syntactically Awesome Stylesheets)应…...

vue组件之间的通信方式有哪些

在开发过程中&#xff0c;数据传输是一个核心的知识点&#xff0c;掌握了数据传输&#xff0c;相当于掌握了80%的内容。 Vue.js 提供了多种组件间的通信方式&#xff0c;这些方式适应不同的场景和需求。下面是4种常见的通信方式&#xff1a; 1. Props & Events (父子组件通…...

111、二叉树的最小深度

给定一个二叉树&#xff0c;找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 题解&#xff1a;找出最小深度也就是找出根节点相对所有叶子结点的最小高度&#xff0c;在这也表明了根节点的高度是变化的&#xff0c;相对不同的叶子结点有不同的高度。…...

SpringBoot3依赖管理,自动配置

文章目录 1. 项目新建2. 相关pom依赖3. 依赖管理机制导入 starter 所有相关依赖都会导入进来为什么版本号都不用写&#xff1f;如何自定义版本号第三方的jar包 4. 自动配置机制5. 核心注解 1. 项目新建 直接建Maven项目通过官方提供的Spring Initializr项目创建 2. 相关pom依…...

音视频开发17 FFmpeg 音频解码- 将 aac 解码成 pcm

这一节&#xff0c;接 音视频开发12 FFmpeg 解复用详情分析&#xff0c;前面我们已经对一个 MP4文件&#xff0c;或者 FLV文件&#xff0c;或者TS文件进行了 解复用&#xff0c;解出来的 视频是H264,音频是AAC&#xff0c;那么接下来就要对H264和AAC进行处理&#xff0c;这一节…...

vue2中封装图片上传获取方法类(针对后端返回的数据不是图片链接,只是图片编号)

在Vue 2中实现商品列表中带有图片编号&#xff0c;并将返回的图片插入到商品列表中&#xff0c;可以通过以下步骤完成&#xff1a; 在Vue组件的data函数中定义商品列表和图片URL数组。 创建一个方法来获取每个商品的图片URL。 使用v-for指令在模板中遍历商品列表&#xff0c;并…...

【C++面向对象编程】(二)this指针和静态成员

文章目录 this指针和静态成员this指针静态成员 this指针和静态成员 this指针 C中类的成员变量和成员函数的存储方式有所不同&#xff1a; 成员变量&#xff1a;对象的成员变量直接作为对象的一部分存储在内存中。成员函数&#xff1a;成员函数&#xff08;非静态成员函数&am…...

最大矩形问题

柱状图中最大的矩形 题目 分析 矩形的面积等于宽乘以高&#xff0c;因此只要能确定每个矩形的宽和高&#xff0c;就能计算它的面积。如果直方图中一个矩形从下标为 i 的柱子开始&#xff0c;到下标为 j 的柱子结束&#xff0c;那么这两根柱子之间的矩形&#xff08;含两端的柱…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...