L01_一条SQL查询语句是如何执行的?

本文详细解析了MySQL的逻辑架构,包括连接器、查询缓存、分析器、优化器和执行器的作用,以及Server层与存储引擎层的分工,以SQL查询为例展示了整个执行流程。

导读

本篇主要通过一条SQL查询语句,让我们初步了解MYSQL基本架构。

在这里插入图片描述

1、MYSQL逻辑架构图

mysql> select * from T where ID=10;

下面是 MySQL 的基本架构示意图,从中你可以清楚地看到 SQL 语句在 MySQL 的各个功能模块中的执行过程。

在这里插入图片描述

2、MySQL的框架有几个组件, 各是什么作用?

连接器
负责和mysql客户端建立连接,获取用户权限,维持和管理连接。连接命令一般是这么写的:

mysql>mysql -h$ip -P$port -u$user -p

连接完成后,如果你没有后续的动作,这个连接就处于空闲状态,你可以在 show processlist 命令中看到它。如图所示,其中的 Command 列显示为“Sleep”的这一行,就表示现在系统里面有一个空闲连接。客户端如果太长时间没动静,连接器就会自动将它断开。这个时间是由参数 wait_timeout 控制的,默认值是 8 小时。命令为:

 mysql>show processlist;
 mysql>show variables like 'wait_timeout';

在这里插入图片描述

查询缓存
查询请求先访问缓存(key 是查询的语句,value 是查询的结果)。命中直接返回。不推荐使用缓存,更新会把缓存清除(关闭缓存:参数 query_cache_type 设置成 DEMAND)。而对于你确定要使用查询缓存的语句,可以用 SQL_CACHE 显式指定,像下面这个语句一样:

 mysql>select SQL_CACHE * from T where ID=10;

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

分析器
分析sql语句是否存在错误,词法分析和语法分析。
优化器
决定使用哪个索引,多表关联(join)的时候,决定各个表的连接顺序。
执行器
执行语句,先判断用户有无查询权限,使用表定义的存储引擎。

mysql> select * from T where ID=10;

比如我们这个例子中的表 T 中,ID 字段没有索引,那么执行器的执行流程是这样的:

(1) 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中;

(2) 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。

(3) 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

3、Server层和存储引擎层各是什么作用?

大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。

Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。

存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。

笔记主要来源参考于林晓斌老师的<<MYSQL实战45讲>>课程,主要用作个人学习笔记记录,如果本文侵犯了您的权益,请联系本人,本人将会在第一时间删除侵权文章!

### `NRF24L01_Send` 函数功能和逻辑 #### 功能 `NRF24L01_Send` 函数的主要功能是通过 NRF24L01 无线模块发送数据,并根据发送结果返回不同的状态码。 #### 逻辑 以下是对函数代码逻辑的详细解释: ```c uint8_t NRF24L01_Send(void)//发送数据 { uint8_t Status; uint8_t SendFlag; uint32_t Timeout; // 设置发送地址和接收通道 0 的地址为相同的发送地址 NRF24L01_Write_Regstates(NRF24L01_TX_ADDR, NRF24L01_TxAddress, 5); NRF24L01_Write_Regstates(NRF24L01_RX_ADDR_P0, NRF24L01_TxAddress, 5); // 将要发送的数据写入发送缓冲区 NRF24L01_TX_PAYLOAD(NRF24L01_TxPacket, NRF24L01_TX_PACKET_WIDTH); // 将 NRF24L01 模块设置为发送模式 NRF24L01_Tx(); // 设置超时时间 Timeout = 10000; // 进入循环,等待发送结果 while (1) { // 读取 NRF24L01 的状态寄存器 Status = NRF24L01_Read_state(); // 超时时间递减 Timeout --; // 如果超时,设置发送标志为 4,表示发送超时 if (Timeout == 0) { SendFlag = 4; // 重新初始化 NRF24L01 模块 NRF24L01_Init(); break; } // 如果状态寄存器的位 4 和位 5 都为 1,表示发送失败且达到最大重发次数 if ((Status & 0x30) == 0x30) { SendFlag = 3; // 重新初始化 NRF24L01 模块 NRF24L01_Init(); break; } // 如果状态寄存器的位 4 为 1,表示发送失败 else if ((Status & 0x10) == 0x10) { SendFlag = 2; // 重新初始化 NRF24L01 模块 NRF24L01_Init(); break; } // 如果状态寄存器的位 5 为 1,表示发送成功 else if ((Status & 0x20) == 0x20) { SendFlag = 1; break; } } // 清除状态寄存器中的发送完成和最大重发次数标志 NRF24L01_WriteReg(NRF24L01_STATUS, 0x30); // 清空发送缓冲区 NRF24L01_FLUSHTX(); // 将接收通道 0 的地址设置为接收地址 NRF24L01_Write_Regstates(NRF24L01_RX_ADDR_P0, NRF24L01_RxAddress, 5); // 将 NRF24L01 模块设置为接收模式 NRF24L01_Rx(); // 返回发送标志 return SendFlag; } ``` ### 总结 该函数首先配置 NRF24L01 模块的发送地址和接收通道 0 的地址,然后将要发送的数据写入发送缓冲区,并将模块设置为发送模式。接着进入一个循环,不断读取状态寄存器,根据状态寄存器的值判断发送结果。如果超时或发送失败,会重新初始化模块。最后,清除状态寄存器标志,清空发送缓冲区,将模块设置为接收模式,并返回发送标志。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值