简单说说MySQL中 SELECT 语句执行流程
流程讲解
MySQL 中 SELECT
语句的执行流程分为多个步骤,通常从用户发出查询请求到 MySQL 返回结果包含以下过程:
-
客户端/服务器通信:
用户向 MySQL 服务器发送SELECT
查询语句。 -
查询解析(Parser):
MySQL 收到 SQL 语句后,会将查询语句进行词法和语法分析。词法分析器将 SQL 语句拆解为关键字、表名、字段名等元素,然后语法分析器根据 MySQL 语法规则检查语句的合法性。 -
预处理:
语法解析后,MySQL 会对查询语句进行预处理,例如:检查表、列是否存在,验证用户的权限等。 -
查询优化器(Optimizer):
这是 MySQL 查询性能的关键步骤。优化器决定如何执行查询,例如选择最优的索引,决定表连接顺序,选择全表扫描还是使用索引等。MySQL 的优化器会生成多个执行计划,选择成本最低的计划。 -
查询执行器(Executor):
执行器根据优化器生成的执行计划去执行查询语句。执行器逐步获取数据,按优化器的指示选择适当的访问方式,如是否使用索引,是否需要回表等。 -
存储引擎层交互:
MySQL 是多存储引擎的系统。执行器根据存储引擎的接口与底层存储引擎交互,获取表中的数据。不同的存储引擎(如 InnoDB、MyISAM)处理查询的方式可能不同。 -
查询缓存(如果启用):
在 MySQL 8.0 之前,如果查询缓存是开启的且查询结果在缓存中,那么 MySQL 可以直接从缓存中返回结果,而不需要继续执行查询。MySQL 8.0 已移除了查询缓存。 -
返回结果:
查询执行完毕后,MySQL 将结果返回给客户端。
select 实例分析
select * from tb_student A where A.age=‘18’ and A.name=’ 张三 ';
针对 SELECT * FROM tb_student A WHERE A.age='18' AND A.name='张三';
这条 SQL 语句,MySQL 的执行流程可以分为如下几个步骤:
1. 客户端/服务器通信
用户在客户端执行该查询,SQL 语句通过网络传递到 MySQL 服务器。
2. 查询解析(Parser)
MySQL 服务器接收到查询语句后,会对 SQL 进行词法和语法解析。
- 词法解析:SQL 语句被拆分为单个关键字或标识符,如
SELECT
、*
、FROM
、tb_student
、WHERE
、A.age
等。 - 语法解析:MySQL 根据 SQL 语法规则检查该查询语句的结构是否正确。如果语法有误,查询会立即失败。
3. 预处理
- 表和列的合法性检查:MySQL 预处理器会检查表
tb_student
是否存在,字段age
和name
是否在表tb_student
中。 - 用户权限检查:MySQL 还会验证当前用户是否有权限访问
tb_student
表并执行查询。
4. 查询优化器(Optimizer)
MySQL 的查询优化器将决定查询的最佳执行方式。对于这条查询,优化器可能做的工作包括:
- 选择合适的索引:如果
age
或name
字段上有索引,优化器可能决定使用索引来加速查询。 - 生成执行计划:优化器会评估多个执行计划,比如先通过
age='18'
过滤数据还是通过name='张三'
过滤,然后选择代价最小的方案。例如,如果age
和name
都有索引,优化器可能会选择一个索引作为主导。
5. 查询执行器(Executor)
查询执行器根据优化器生成的执行计划执行查询。假设 age
字段上有索引,那么执行器会:
- 使用索引快速找到
age=18
的记录。 - 然后根据
name='张三'
的条件进一步筛选数据。
6. 存储引擎层交互
执行器与底层存储引擎(如 InnoDB)交互,按执行计划获取数据。存储引擎会根据执行器的指令进行:
- 读取操作:如果涉及到索引查找,存储引擎可能只需要扫描部分数据,而不是全表扫描。
- 回表操作:如果使用了覆盖索引且所需字段都能从索引中获取,则直接返回;否则可能需要回表(通过主键索引)来获取
*
(即所有列)。
7. 过滤和处理
执行器对查询结果进行过滤,确保返回的数据满足 age='18'
和 name='张三'
两个条件。MySQL 将把符合条件的数据组装成查询结果集。
8. 返回结果
查询结果被发送回客户端,完成 SQL 语句的执行。