《MySQL》系列 - select 查询语句到底是怎么执行的?

mysql中select的执行流程 描述:MySQL数据库由Server层和存储引擎层组成。Server层是处理客户端请求、SQL语句解析和优化的中心,而存储引擎层则负责数据的物理存储和索引。总结SELECT查询语句执行的关键步骤强调优化器和索引在查询性能中的重要性总结本文深入探讨了MySQL执行SELECT查询语句的内部机制,从连接器的连接建立到查询缓存的检查,再到解析器、预处理器、优化器和执行器的协同工作,最后由存储引擎完成数据的检索。连接器确保了安全、有效的连接,并进行了用户认证。查询缓存。 阅读详情

mysql 作为一个关系型数据库,在国内使用应该是最广泛的。也许你司使用 Oracle、Pg 等等,但是大多数互联网公司,比如我司使用得最多的还是 Mysql,重要性不言而喻。

事情是这样的,某天我司小胖问我执行select * from table,数据库底层到底发生了啥?从而我们得到数据呢?以下把我给问住了,为此我查阅了大量的书籍、博客。于是就有了这篇文章。

假设现在我有张 user 表,只有两列,一列 id 自增的,一列 name 是 varchar 类型。建表语句是这样的:

CREATE TABLE IF NOT EXISTS `user`(
   `id` INT UNSIGNED AUTO_INCREMENT,
   `name` VARCHAR(100) NOT NULL,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
复制代码

小胖的问题就是下面这个语句的执行过程。

select * from user where id = 1; 
复制代码

01 mysql 架构概览

要想理解这个问题就必须要知道 mysql 的内部架构。为此,我画了张 mysql 的架构图(你也可以理解为 sql 查询语句的执行过程),如下所示:

Mysql架构图

首先 msql 分为 server 层和存储引擎层两个部分。server 层包括四个功能模块,分别是:连接器、查询缓存、优化器、执行器。这一层负责了 mysql 的所有核心工作,比如:内置函数、存储过程、触发器以及视图等。

而存储引擎层则是负责数据的存取。注意,存储引擎在 mysql 是可选的,常见的还有:InnoDB、MyISAM 以及 Memory等,最常用的就是 InnoDB。现在默认的存储引擎也是它(从 mysql 5.5.5 版本开始),大家可以看到我上面的建表语句就是指定了 InnoDB 引擎。当然,你不指定的话默认也是它。

由于存储引擎是可选的,所以 mysql 中,所有的存储引擎其实是共用一个 server层的。回到正题,我们就以这张图的流程来解决一下小胖的问题。

1.1 连接器

首先,数据库要执行 sql,肯定要先连接数据库吧。这部分工作就是由连接器完成。它负责校验账户密码、获取权限、管理连接数,最终与客户端建立连接等工作。mysql 链接数据库是这样写的:

mysql -h 127.0.0.1 -P 3306 -u root -p
# 127.0.0.1 : ip 3306 : 端口 root : 用户名
复制代码

运行命令之后需要输入密码,当然也可以跟在 -p 后面。不过不建议这么做,会有密码泄露的风险。

输入命令后,连接器根据你的账户名密码验证身份。这是会出现两种情况:

  • 账号或密码不对,服务端会返回一个 "ERROR 1045 (28000): Access denied for user 'root'@'127.0.0.1' (using password: YES)" 的错误,退出连接。
  • 验证通过,连接器就会到权限表查出你的权限。之后你有啥权限都要通过这时读到的权限进行判断。

注意,我说的是此时查到的权限。就算你用管理员账号修改了当前用户的权限,此时已连接上的当前用户不受影响,必须要重启 mysql 新的权限才会生效。

1.1.1 查看连接状态

连接完成,如果后续没有做任何事情,这个连接就处于空闲状态。你可以用 show processlist; 命令查看 mysql 的连接信息,如下图,我的数据库连接都是 Sleep 状态的,除了执行 show processlist 操作的连接。

show processlist;

1.1.2 控制连接

如果客户端太长时间没有操作,此连接将会自动断开。这个时间默认是 8 小时,由参数 wait_timeout 控制。如果断开以后继续操作就会收到 "Lost connection to MySQL server during query"的错误。这时就必须重连才能执行请求。

数据库里面有长短连接之分,长连接:连接成功后不断有请求,就会一直使用同一连接。短连接:每次执行完几次请求就断开连接,下次需要再建立。

由于建立连接是比较耗时的操作,所以建议使用长连接。但这会有个问题长连接一直连着就会导致内存占用过大,被系统强行沙雕。从而导致 MySQL 异常重启。如何解决呢?两个方法:

  • 定期断开长连接。使用特定时间,或者程序判断执行一个占用内存大的操作后,断开连接。之后需要操作就重连。
  • mySQL 5.7 或以上版本,可以在每次执行一个占用内存大的操作后,执行mysql_reset_connection来重新连接资源,此时不需重连或重新做权限认证,但会把连接状态恢复到刚创建完时。

1.2 查询缓存

连接建立以后可以执行 select 语句了。这就会来到第二步:查询缓存。

查询缓存中存储的数据是 key-value 的形式,key 是查询语句,value 是查询的结果。逻辑是这样的:先看看查询缓存有没该语句对应的 value?有则直接取出返回客户端,无则继续到数据库执行语句。查出结果后会放一份到缓存中,再返回客户端。

你可能发现缓存真的香,但是并不建议使用查询缓存,因为有弊端。查询缓存的失效非常频繁,只有某个表有更新。它马上失效了,对于经常更新的表来说,命中缓存的概率极低。它仅仅适用于那些不经常更新的表。

而 MySQL 似乎也考虑到这点了。提供了 query_cache_type 参数,把它设置为 DEMAND 就不再适用韩村。而对于要使用缓存的语句则可用 SQL_CACHE 显示指定,像这样:

select SQL_CACHE * from user where id = 1;
复制代码

PS:MySQL 8.0 及以上版本把查询缓存删掉了,之后再也没有这块功能了。

1.3 分析器

如果没有命中缓存就进入分析器,这里就是对 sql 进行分析。分析器会做词法分析。你输入的 sql 是啥,由啥组成,MySQL 都需要知道它们代表什么。

首先根据 "select" 识别出这是查询语句。字符串"user"识别成"表名 user"、字符串"id"识别成"列名id"。

之后进行语法分析,它会根据输入的语句分析是不是符合 MySQL 的语法。具体表现就是 select、where、from 等关键字少了个字母,明显不符合 MySQL 语法,这次就会报个语法错误的异常:它一般会提示错误行数,关注"use near"后面即可。

语法错误

1.4 优化器

过了分析器,就来到了优化器。MySQL 是个聪明的仔,再执行之前会自己优化下客户端传过来的语句,看看那种执行起来不那么占内存、快一点。比如下面的 sql 语句:

select * from user u inner join role r on u.id = r.user_id where u.name = "狗哥" and r.id = 666
复制代码

它可以先从 user 表拿出 name = "狗哥" 记录的 ID 值再跟 role 表内连接查询,再判断 role 表里面 id 的值是否 = 666

也可以反过来:先从 role 表拿出 id = 666 记录的 ID 值再跟 user 表内连接查询,在判断 user 表里面的 name 值是否 = "狗哥"。

两种方案的执行结果是一样的,但是效率不一样、占用的资源也就不一样。优化器就是在选择执行的方案。它优化的是索引应该用哪个?多表联查应该先查哪个表?怎么连接等等。

1.5 执行器

分析器知道了做啥、优化器知道了应该怎么做。接下来就交给执行器去执行了。

开始执行,判断是否有相应的权限。比如该账户对 user 表没权限就返回无权限的错误,如下所示:

select * from user where id = 1;

ERROR 1142 (42000): SELECT command denied to user 'nasus'@'localhost' for table 'user'
复制代码

PS:如果命中缓存没走到执行器这里,那么在返回查询结果时做权限验证。

回到正题,如果有权限,继续打开表执行。执行器会根据表定义的引擎去使用对应接口。比如我们上面的 sql 语句执行流程是这样的:

  • 走 id 索引、调用 InnoDB 引擎取"满足条件的第一行"接口,再循环调用"满足条件的下一行"接口(这些接口都是存储引擎定义好的),直到表中不再有满足条件的行。执行器就将上述遍历得到的行组成结果集返回给客户端。

  • 对于 id 不是索引的表,执行器只能调用"取表记录的第一行"接口,再判断 id 是否 = 1。如果不是则跳过,是则存在结果集中;再调存储引擎接口取"下一行",重复判断逻辑,直到表的最后一行。

至此,整个 SQL 的执行流程完毕,小胖懂了吗?

巨人的肩膀

总结

本文通过一条简单的 SQL 查询语句,引出 MySQL 的结构以及这条 sql 查询语句的执行流程。相信你看完会对 SQL 有更深的理解。

MySQL查询语句中关键字的执行顺序 了解MySQL查询语句关键字的执行顺序对于理清业务逻辑非常重要,因此本文将探讨MySQL查询语句中各关键字的执行顺序。 阅读详情

相关推荐

MySQL--select基础查询语句

MySQL--select查询语句MySQL--Workbench一、Select查询语句(MySQL不区分大小写)1、这里我们先创建四张表,分别模拟某高校部分学生三门课程成绩考试得分情况, MySQL–Workbench 一、Select查询语句(MySQL不区分大小写) 1、这里我们先创建四张表,分别模拟某高校部分学生三门课程成绩考试得分情况, ...

L1542334210的博客 1087

面试阿里必知的SQL面试题 100讲

SQL 常见面试题解析 内容简介 本文介绍并分析了 100 道常见 SQL 面试题,主要分为三个模块:SQL 初级查询、SQL 高级查询以及数据库设计与开发。文章内容结构如下图所示: 本文主要使用三个示例表:员工表(employee)、部门表(department)和职位表(job)。下面是这些示例表的结构图: 部门表(department),包含部门编号(dept_id)和部门名称(dept_n...

快乐的工程师的博客 1万+

用于可靠的钙钛矿薄膜瞬时光致发光模拟的拟合程序

简介 对光激发后的电荷载流子动态的研究对于确定太阳能电池的几个特性至关重要,例如,体和界面重组的数量以及向电荷传输层转移过程的速度。 瞬态光致发光(trPL)是用于研究这些特性的最流行的表征方法之一。 该实验是通过在样品上照射几纳秒的激光脉冲,并记录一段时间内的发光情况来进行的。辐射性重组的光生电荷载流子将引起太阳能电池的光子发射,而非辐射性重组的电荷载流子将不会对发光作出贡献。因此,可以测量到强度随时间递减的光致发光瞬态。(见图1表示trPL的测量和它的输出)。 图1. 一...

FluximAG的博客 2362

sql 为什么要用where 1=1或者where 1 =0 ?

一、不用where 1=1 在多条件查询中的困扰   举个例子,如果您做查询页面,并且,可查询的选项有多个,同时,还让用户自行选择并输入查询关键词,那么,按平时的查询语句的动态构造,代码大体如下: 代码如下:   string MySqlStr=”select * from table where”;   if(Age.Text.Lenght>0)   {     MySqlStr=MySqlStr+“Age=“+“'Age.Text'“;   }   if(Address.Text...

一缕阳光的博客 1247

QTableView为例:Qt模型视图委托(MVD)(Model-View-Delegate)

QT中的MVD(模型-视图-委托)模式是一种类似于MVC的设计模式,将数据、界面和交互逻辑分离。模型负责数据管理,视图负责显示界面,而委托则嵌入在视图中处理数据的显示和编辑。QT提供了多种视图组件(如QListView、QTreeView、QTableView)和模型类(如QStandardItemModel、QAbstractItemModel),支持数据的多样化呈现。委托(Delegate)通过定制显示和编辑行为增强了视图的灵活性。该模式适用于各类数据结构展示(列表、表格、树形),能够高效处理数据与界面

菜一头包的博客 1988

ESP32 STA AP模式下,设备连接 ESP的AP 后无法上网,无法访问域名上网(或者Failed to enable NAPT)

ESP32 STA AP模式下,设备连接 ESP的AP 后无法上网,无法访问域名上网(或者Failed to enable NAPT)1.可能是ESP STA模式未成功连接到路由器,确保 STA 成功连接到外部网络。2.检查 STA 和 AP 的网络配置是否正确,避免子网冲突。3.ESP32的NAPT功能未正确启用,确保 menuconfig 中已启用 IP_NAPT。4.DNS服务器未正确配置。

qq_34885669的博客 1539

mysql8.x版本_select语句源码跟踪

HAVE_PSI_THREAD_INTERFACE 是一个编译器宏,用于表示是否支持 PSI(Process Status Interface)线程接口。在 C++ 编程语言中,这个宏通常用于条件编译,以便根据编译器和系统的支持情况来选择性地包含或排除与 PSI 相关的代码。gtid_consistency_violation_state变量表示当前线程是否存在GTID一致性违规状态。connection_handler_per_thread.cc:245 -> 最后走的是do_command()函数。

飞奔的屎壳郎 1536

世界坐标系/相机坐标系/图像坐标系 转换

目录一、各坐标系简要介绍二、坐标系转换2.1 世界坐标系转为相机坐标系2.2 相机坐标系转为物理图像坐标系2.3 物理图像坐标系转为图像坐标系2.4 总结2.5 为什么要使用齐次坐标参考文献 一、各坐标系简要介绍 首先介绍数字图像处理领域中的图像坐标系,如上图左图所示,坐标系O_0为图像坐标系,其原点是在图像的左上角,每一个像素通过其所在位置的列数和行数索引 (u,v) 来表示。 另外需要建立图像坐标与物理单位的关系,而后才能将目标的真实世界坐标转换为图像坐标。即建立以物理单位表示的物理图像坐标系(有些文

流觞时光 1万+

mysql查询语句底层的执行流程

引入 我去查询T表中 ID为10的数据,我们通常只是看到得到一条结果。其中的过程还不太清楚,如何找到这条数据,先做的什么再做的什么?看到的只是输入一条语句,返回一个结果,却不知道这条语句在 MySQL 内部的执行过程。 mysql> select * from T where ID=10; 这里把MYSQL拆解下,看看它的组成,经过这个拆解的过程更深入的理解Mysql,当碰到Mysql一些异常和问题,能够看到本质,快速定位与解决。 层层刨析MYSQL基本架构 下图MySQL 的基本架构示

银魄清辉自夜凝的博客 431

网站进行企业微信授权登录(附带代码超详细版)

企业微信的扫码登录官方文档 https://work.weixin.qq.com/api/doc/90000/90135/90988 企业微信扫码登录认证流程 上面是官方的图片,看上去比较复杂。因此我用直白简洁的语言梳理下流程。 1、首先在自己的网站上获取到企业微信登录的二维码(二维码怎么获取稍后再说,这里想象下你已经有了一个二维码) 2、你拿着手机扫描二维码,确认登录之后,页面就会自己进行重定向的跳转,跳转的url如何配置下面再讲,但是注意,这个重定向的url可以是内网地址 3、重定向到指

Gzf的博客 1万+

《UE4游戏开发》之 《音效系统的实现》

音效系统需要负责管理什么事情: 1.1 确定声音控制的分类:如背景音乐、技能音效、界面音效、角色配音等,不同游戏对声音有不同的分类 1.2 控制每个分类的声音的开启与关闭,以及调节每个分类声音的大小 解决如何分类: 2.1 首先需要知道ue4为声音分类提供了什么:SoundClass通常需要一个根分类【SC_RPG_Master】,便于总体控制音效,以及指定引擎默认启动的音效 打开SoundClass资产【SC_RPG_Master】,对根控制的设置,将逐级传递并按比例进行设置,以此达到控制一类声音的目的.

qq_21919621的博客 2126

MySQL中select查询语句的执行过程

本文详细介绍了MySQL查询语句的执行过程,包括SQL组件介绍、执行顺序和执行流程。MySQL查询分为Server层和存储引擎层,Server层包含连接器、查询缓存、解析器、优化器和执行器等组件。文章重点解析了SELECT语句的执行流程,从连接认证到语法解析、预处理、优化器生成执行计划,再到执行器与存储引擎交互,最后返回结果。此外,还介绍了流式查询的实现方式,如JDBC流式Statement和MyBatis的ResultHandler接口,以避免大数据量查询时的内存溢出问题。最后提供了常见性能优化建议和参考

weixin_50055999的博客 2019

RT-DETR改进前必看 - Ultralytics调参 1:1还原RT-DETR官方版本实验环境,更方便改进

的项目文件中集成了YOLOv3v5v6v8v9v10rt-detr11以及其中不同大小的模型结构,更方便我们学习和使用。的参数配置在路径下,其中中设置了模型在训练Train验证Val/Test预测Predict可视化Visualize导出Export超参数Hyperparameters、以及跟踪Tracker的相关参数。在调参过程中主要涉及训练Train和超参数Hyperparameters。下面主要介绍一下初始超参数Hyperparameters。

Limiiiing的博客 7959

MySQL中SELECT语句的执行过程

使用组合索引时,可能会有部分字段无法使用到索引,这时可以使用索引下推来减少回表操作,索引下推就是将所有查询条件都判断完成后再回表,没有使用索引下推就只判断了使用到索引的字段,其余字段的查询条件还需要回到Server层来判断。组合索引当遇到范围查询 (>、<) 就会停止匹配,也就是。

boluomi的博客 3256

【RT-DETR涨点改进】全网独家首发、注意力改进篇 | ICLR 2026 | 引入 MHLA 多头线性注意力,关注不同的上下文区域,弥补卷积的长程依赖建模方面的不足,助力高效涨点,来自北京大学

🔥本文提出MHLA多头线性注意力模块,用于改进RT-DETR目标检测网络。MHLA通过恢复线性注意力的表达能力,在保持线性复杂度的同时,为网络提供高效的全局上下文建模能力。该方法解决了传统线性注意力在长序列建模中的"全局上下文坍塌"问题,使不同空间位置能关注不同上下文区域。实验表明,MHLA显著提升了RT-DETR在复杂背景、小目标和遮挡场景下的检测性能,且不增加显著计算开销。文章详细介绍了MHLA的原理、优势及8种改进方案,并提供了完整的代码实现和配置指南。

Ai缝合怪、助力小伙伴高效发论文 271

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

MySQL查询语句执行顺序详解

理解MySQL查询语句的执行顺序有助于编写更高效的查询。通过合理安排各个子句,我们可以更好地控制查询的行为和性能。希望这篇文章能帮助你更好地理解MySQL查询的执行过程,提高SQL查询优化的能力。

Java领域优秀创作者 1934

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

MySQL 学习(十)执行一条查询语句的内部执行过程、MySQL分层

MySQL 学习(十)执行一条查询语句的内部执行过程、MySQL分层

ACGkaka的博客 2022

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

简单说说MySQL中 SELECT 语句执行流程

MySQL 中SELECT用户向 MySQL 服务器发送SELECT查询语句。MySQL 收到 SQL 语句后,会将查询语句进行词法和语法分析。词法分析器,然后语法分析器根据 MySQL 语法规则。。这是 MySQL。优化器决定如何执行查询,。MySQL 的优化器会生成多个执行计划,选择成本最低的计划。执行器根据优化器生成的执行计划去执行查询语句。,按优化器的指示选择适当的访问方式,如是否使用索引,是否需要回表等。MySQL 是多存储引擎的系统。

程序员诚哥 1653

Mysql中Select语句的执行顺序

今天同事问了我个问题,select语句中的别名可以在哪些地方使用,一听这个我就想到了聚合函数、group by、having、order by。然后它又问我可以在 join on中使用嘛?,我陷入了思考,想了下这其实跟select语句的执行顺序有关,因为记不太清了,所以再次学习了下,并记录一下。本文总结了mysql中select的执行顺序,并对几个常见的疑问进行了解答,希望能对你有所帮助。

sky2019116的博客 2276

原来一条select语句在MySQL是这样执行的《死磕MySQL系列 一》

原来一条select语句在MySQL是这样执行的

咔咔博客 4439

MySQL SELECT 查询(一):基础查询语句的实现

MySQL SELECT 查询(一):基础查询语句的实现,包括select语句的结构,where过滤,order by 排序,group by分组,limit 的介绍以及使用

2301_77207909的博客 2774

MySQL查询语句的执行流程

这篇文章主要从一条查询的sql语句入手,从发起查询,客户端与服务端建立起连接起手,深入到MySQL的存储引擎,为大家展现sql语句的一整套执行流程。

weixin_74120671的博客 1157

Mysql中查询语句的执行顺序

关于mysql查询语句的执行顺序也是面试和笔试中常问的考点之一,下面我们以实际的查询语句来看看查询语句的执行顺序到底是怎么样的。

shangshanzixu的博客 656

MySQL的分析查询语句

通过对查询语句进行分析,可以了解查询语句的执行情况,找出查询语句执行的瓶颈,从而优化查询语句。MySQL中提供了和来分析查询语句。

夏天又到了的专栏 1058

MySQL 查询常用操作(0) —— 查询语句的执行顺序

MySQL中明确查询语句的执行顺序极其重要,了解执行顺序才不至于犯一些简单错误,例如having 后面是否可以使用 select 中的数据等问题。另外SQL中实际使用最频繁的就是查询,要想写出高质量、高性能的查询语句,必须深入地了解SQL的逻辑查询处理顺序和机制。

我的博客 2445
上一篇: 面试官:群聊消息的已读未读功能,你来设计一个?
下一篇: 分布式接口幂等性、分布式限流(Guava 、nginx和lua限流)
superjava_
博客等级 码龄5年 254粉丝 81原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值