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 的柱子结束,那么这两根柱子之间的矩形(含两端的柱…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...
JavaScript 标签加载
目录 JavaScript 标签加载script 标签的 async 和 defer 属性,分别代表什么,有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...
Qt 按钮类控件(Push Button 与 Radio Button)(1)
文章目录 Push Button前提概要API接口给按钮添加图标给按钮添加快捷键 Radio ButtonAPI接口性别选择 Push Button(鼠标点击不放连续移动快捷键) Radio Button Push Button 前提概要 1. 之前文章中所提到的各种跟QWidget有关的各种属性/函数/方法&#…...
2025-06-01-Hive 技术及应用介绍
Hive 技术及应用介绍 参考资料 Hive 技术原理Hive 架构及应用介绍Hive - 小海哥哥 de - 博客园https://cwiki.apache.org/confluence/display/Hive/Home(官方文档) Apache Hive 是基于 Hadoop 构建的数据仓库工具,它为海量结构化数据提供类 SQL 的查询能力…...
智能照明系统:具备认知能力的“光神经网络”
智能照明系统是物联网技术与传统照明深度融合的产物,其本质是通过感知环境、解析需求、自主决策的闭环控制,重构光与人、空间、环境的关系。这一系统由智能光源、多维传感器、边缘计算单元及云端管理平台构成,形成具备认知能力的“光神经网络…...
