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 的柱子结束,那么这两根柱子之间的矩形(含两端的柱…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
