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表空间相关的内容。包括区、段、碎片区,还有一些不同的页类型的作用。 (如果没有看前面五篇文章,不建议看此篇文章) 传送门: 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文件,可以通过右键项目-资源-常规-添加创建或打开程序集资源 2.添加国际化字符串 打开Resources.resx文件,添加需要翻译的文本字符,并将访问修…...
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、先求出以矩阵中的每个单元格为起点的最长递增路径 题目中说,对于每个单元格,你可以往上,下,左,右四个方向移动。那么以一个单元格为起点的最长递增路径就是:从该单元格往上…...
语音深度鉴伪识别项目实战:基于深度学习的语音深度鉴伪识别算法模型(二)音频数据预处理及去噪算法+Python源码应用
前言 深度学习技术在当今技术市场上面尚有余力和开发空间的,主流落地领域主要有:视觉,听觉,AIGC这三大板块。 目前视觉板块的框架和主流技术在我上一篇基于Yolov7-LPRNet的动态车牌目标识别算法模型已有较为详细的解说。与AIGC相…...
网络原理——http/https ---http(1)
T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 今天你敲代码了吗 网络原理 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
理论 摘自:USB 主机和配件概览 | Connectivity | Android Developers (google.cn) Android 通过 USB 配件和 USB 主机两种模式支持各种 USB 外围设备和 Android USB 配件(实现 Android 配件协议的硬件)。 在 USB 主机模式下࿰…...
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 为例,使用模态框编写一个简单的消息框: import { useState } from "react"; import { Modal } from "react-bootstrap"; import Button from "react-bootstrap/Button"; import bootstrap/dist/css/b…...
tomcat10部署踩坑记录-公网IP和服务器系统IP搞混
1. 服务器基本条件 使用的阿里云服务器,镜像系统是Ubuntu16.04java version “17.0.11” 2024-04-16 LTS装的是tomcat10.1.24阿里云服务器安全组放行了:8080端口 服务器防火墙关闭: 监听情况和下图一样: tomcat正常启动ÿ…...
探索Sass:Web开发的强大工具
在现代Web开发中,CSS(层叠样式表)作为前端样式设计的核心技术,已经发展得非常成熟。然而,随着Web应用的复杂性不断增加,传统的CSS书写方式逐渐暴露出一些不足之处,如代码冗长、难以维护、缺乏编程功能等。为了解决这些问题,Sass(Syntactically Awesome Stylesheets)应…...
vue组件之间的通信方式有哪些
在开发过程中,数据传输是一个核心的知识点,掌握了数据传输,相当于掌握了80%的内容。 Vue.js 提供了多种组件间的通信方式,这些方式适应不同的场景和需求。下面是4种常见的通信方式: 1. Props & Events (父子组件通…...
111、二叉树的最小深度
给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 题解:找出最小深度也就是找出根节点相对所有叶子结点的最小高度,在这也表明了根节点的高度是变化的,相对不同的叶子结点有不同的高度。…...
SpringBoot3依赖管理,自动配置
文章目录 1. 项目新建2. 相关pom依赖3. 依赖管理机制导入 starter 所有相关依赖都会导入进来为什么版本号都不用写?如何自定义版本号第三方的jar包 4. 自动配置机制5. 核心注解 1. 项目新建 直接建Maven项目通过官方提供的Spring Initializr项目创建 2. 相关pom依…...
音视频开发17 FFmpeg 音频解码- 将 aac 解码成 pcm
这一节,接 音视频开发12 FFmpeg 解复用详情分析,前面我们已经对一个 MP4文件,或者 FLV文件,或者TS文件进行了 解复用,解出来的 视频是H264,音频是AAC,那么接下来就要对H264和AAC进行处理,这一节…...
vue2中封装图片上传获取方法类(针对后端返回的数据不是图片链接,只是图片编号)
在Vue 2中实现商品列表中带有图片编号,并将返回的图片插入到商品列表中,可以通过以下步骤完成: 在Vue组件的data函数中定义商品列表和图片URL数组。 创建一个方法来获取每个商品的图片URL。 使用v-for指令在模板中遍历商品列表,并…...
【C++面向对象编程】(二)this指针和静态成员
文章目录 this指针和静态成员this指针静态成员 this指针和静态成员 this指针 C中类的成员变量和成员函数的存储方式有所不同: 成员变量:对象的成员变量直接作为对象的一部分存储在内存中。成员函数:成员函数(非静态成员函数&am…...
最大矩形问题
柱状图中最大的矩形 题目 分析 矩形的面积等于宽乘以高,因此只要能确定每个矩形的宽和高,就能计算它的面积。如果直方图中一个矩形从下标为 i 的柱子开始,到下标为 j 的柱子结束,那么这两根柱子之间的矩形(含两端的柱…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
