MySQL 一条select 语句是怎么执行的

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。而存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。

一条sql查询语句是如何执行的。

通过mysql的执行计划(explain) 探寻select 语句的神秘

explain select * from course_order where id > 10;

下图为执行后的结果

image.jpeg

explain 中的列描述

id列

标识select 所属的行。如果语句汇当中没有子查询或联合,那么只会有唯一的select,于是每一行在这个列中都将显示一个1。否则,内存select语句一般会顺序编号,对应与其在原始语句汇总的位置。


select查询分简单和复杂类型

复杂类型分成三大类:简单子查询、所谓的派生表(在from子句中的子查询),以及union查询


三类语句的混合则会使输出变得非常复杂。


select_type 列

这一列显示了对应行是简单还是复杂select。simple值意味着查询不包括子查询和union。如果查询有任何复杂的子部分,则最外层部分标记为primary,其他部分标记如下:

subquery:包含在select列表中的子查询中的select标记为subquery

derived:用来标识包含在from子句的子查询中的select,mysql会递归执行并将结果放到一个临时表中。服务器内部称其“派生表”,因为该临时表是从子查询中派生来的。

union:在union中的第二个和随后的select被标记为union。第一个select被标记就好像它以部分外查询来执行。这就是之前的例子中在union中的第一个select显示为primary的原因。如果union被from子句中的子查询包含,那么它的第一个select会被标记derived。

union result:用来从union的匿名临时表检索结果的select被标记为union result


table列

显示对应行正在访问哪个表。是一个表,或者是标的别名。

可以在这一列中从上往下观察mysql的关联优化器为查询选择的关联顺序。


type列

显示了"关联类型",更准确的说法是访问类型-换言之就是Mysql决定如何查找表中的行。下面依次从最差到最优

ALL 全表扫描

index 跟全表扫描一样,只是扫描表时按索引次序进行而不是行。主要避免了排序。缺点是要承担按索引次序读取这个表的开销。

range 范围扫描就是一个有限制的索引扫描,它开始与索引里的某一点,返回匹配这个值域的行。这比全索引扫描好一些。扫描是带有between或在where子句中带有>的查询

ref 这是一种索引访问,它返回所有匹配某单个值的行。它是查找和扫描的混合体。只有当使用非唯一性索引或者唯一性索引的非唯一性前缀时才会发生。

eq_ref 使用这种索引查找,最多只返回一条符合条件的记录。以使用主键或者唯一索引查找时看到。

const,system 对查询的某些部分进行优化将其转换成一个常量时

null 意味着mysql能再优化阶段分解查询语句,执行阶段用不着访问表或者索引。


possible_keys 列

这一列显示了查询可以使用那些索引,这是基于查询访问的列和使用的比较操作符来判断。这个列表是在优化过程的早期创建的,因此有些罗列出来的索引可能对于后续优化过程是没用的。


key列

该列显示了Mysql决定采用哪个索引来优化对该表的访问。如果该索引没有出现在possible_keys列中,那么选用它是出于另外的原因,它可能选择了一个覆盖索引,哪怕没有where子句。


key显示的是优化采用了最小化查询成本的那个索引。


key_len 列

显示了在索引里使用的字节数。指的是此次索引匹配上的字节大小,非数据表中的对应数据大小。


ref列

这一列显示了之前的表在key列记录的索引查找值所用的列或常量。


rows列

估计为了找到所需的行而要读取的行数。这个数组是内嵌循环关联计划里的循环数目。估算的值,并不精准。


filtered列

在使用explain extended时出现(可能随着版本的演进,高版本默认出现了,我刚刚就出现了)显示的是针对表里符合某个条件的记录数的百分比所做的一个悲观估算。


Extra列

这一列包含的是不适合在其他列显示的额外信息。

using index 此值标识使用覆盖索引,以避免回表

using where 将在存储引擎检索行后再进行过滤。许多where条件里涉及索引中的列,当它读取索引时,就能被存储引擎检验,出现时可能表示查询可受益于不同的索引

using temporary 对查询结果排序时会使用一个临时表

using filesort 会对结果使用一个外部索引排序,而不是按索引次序从表里读取行

range checked for each recor (index map :N)以为着没有好用的索引,新的索引将链接的每一行上重新估算。


Java 编程规约推荐

image.jpeg


大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。而存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。


不同的存储引擎公用一个Server层

连接器

mysql -hlocolhost -P3306 -uroot -p

show processlist  -》 查看数据库连接列表,command列表示状态 对应的Sleep值意为空闲连接,太长时间没动静,自动断开,参数为wait_timeout管理,默认值为8小时。

查询缓存

MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中。key 是查询的语句,value 是查询的结果。如果你的查询能够直接在这个缓存中找到 key,那么这个 value 就会被直接返回给客户端。

系统配置表适合使用查询缓存,数据表为静态的,一旦表被更新,该表对应的缓存将全部失效,对于更新频繁的表来说,查询缓存毫无意义。


好在 MySQL 也提供了这种“按需使用”的方式。你可以将参数 query_cache_type 设置成 DEMAND,这样对于默认的 SQL 语句都不使用查询缓存。而对于你确定要使用查询缓存的语句,可以用 SQL_CACHE 显式指定,像下面这个语句一样:

mysql>select SQL_CACHE *from T where ID=10

需要注意的是,MySQL 8.0 版本直接将查询缓存的整块功能删掉了,也就是说 8.0 开始彻底没有这个功能了。


分析器

进行词法分析语法分析,如果出现问题将会报错


优化器

到了这里,数据库已经知道要做什么了,就开始进行优化了。

优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。


执行器

MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。

开始执行的时候,要先判断一下你对这个表 T 有没有执行查询的权限

打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。


调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中;调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。


以上就是mysql 中一条select 语句的执行流程了,大家加油!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
25天前
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
3月前
|
SQL 关系型数据库 MySQL
SQL语句编写的练习(MySQL)
这篇文章提供了MySQL数据库中关于学生表、课程表、成绩表和教师表的建表语句、数据插入示例以及一系列SQL查询练习,包括查询、排序、聚合和连接查询等操作。
|
3月前
|
存储 关系型数据库 MySQL
在 MySQL 中使用 Insert Into Select
【8月更文挑战第11天】
586 0
在 MySQL 中使用 Insert Into Select
|
4月前
|
存储 关系型数据库 文件存储
面试题MySQL问题之简单的SELECT操作在MVCC下加锁如何解决
面试题MySQL问题之简单的SELECT操作在MVCC下加锁如何解决
49 2
|
5月前
|
关系型数据库 MySQL Linux
mysql 将select结果导出文件 linux
mysql 将select结果导出文件 linux
67 3
|
4月前
|
关系型数据库 MySQL 索引
MySQL之优化SELECT语句
以上只是一些基本的优化策略,具体的优化方案还需要根据实际的业务需求和数据情况来定制。
50 0
|
5月前
|
关系型数据库 MySQL 数据库
MySQL SELECT查询实战:练习题精选,提升你的数据库查询技能
MySQL SELECT查询实战:练习题精选,提升你的数据库查询技能
|
5月前
|
SQL 关系型数据库 MySQL
深入探索MySQL SELECT查询:从基础到高级,解锁数据宝藏的密钥
深入探索MySQL SELECT查询:从基础到高级,解锁数据宝藏的密钥
|
14天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
29 1
|
16天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
30 4

热门文章

最新文章

下一篇
无影云桌面