欢迎光临
我们一直在努力

【Mysql】执行SQL查询语句的过程

这张图讲的是:客户端发送一条 SELECT 查询语句后,MySQL 内部是怎么一步步处理并返回结果的。

image.png

可以按图上的编号理解。


1. 连接器:先建立连接

客户端要执行 SQL,首先要和 MySQL 服务端建立连接。

比如你用 Java 程序连接 MySQL:

select * from user where id = 1;

SQL 不会直接去数据库文件里查,而是先通过网络协议发给 MySQL Server。

连接器主要做三件事:

  • 建立 TCP 连接;
  • 校验用户名和密码;
  • 判断当前用户有没有权限。
  • 例如:

    mysql u root p

    输入密码后,连接器会验证你是不是合法用户。

    连接成功之后,这个连接会保持一段时间,后续 SQL 都通过这个连接发送。


    2. 查询缓存:看看以前有没有查过

    查询缓存的作用是:

    如果之前执行过一模一样的 SQL,并且表数据没有变化,就直接返回缓存结果。

    比如之前执行过:

    select * from user where id = 1;

    如果缓存中有结果,就不用继续解析、优化、执行了,直接返回。

    但是这个模块在 MySQL 8.0 已经被删除。

    原因是查询缓存很容易失效。

    比如 user 表中任何一条数据发生变化:

    update user set name = 'Tom' where id = 2;

    哪怕你查的是 id = 1,这个表相关的查询缓存也可能被清空。

    所以查询缓存看似提高性能,但在更新频繁的系统中反而维护成本很高。

    现在面试里你可以这样说:

    MySQL 8.0 之前有查询缓存,如果命中可以直接返回结果;但由于缓存失效频繁,实际收益不高,所以 MySQL 8.0 已经移除了查询缓存。


    3. 解析器:检查 SQL 写得对不对

    如果没有命中查询缓存,就进入解析器。

    解析器主要做两步:

    第一步:词法分析

    把 SQL 拆成一个个单词,识别每个词是什么意思。

    例如:

    select name from user where id = 1;

    MySQL 会识别出:

    select 是关键字
    name 是字段名
    from 是关键字
    user 是表名
    where 是关键字
    id 是字段名
    1 是常量

    第二步:语法分析

    检查 SQL 语法是否符合 MySQL 规则。

    比如你写成:

    select from user where id = 1;

    少了查询字段,语法分析就会报错。

    如果语法正确,解析器会生成一个 语法树。

    你可以把语法树理解成 MySQL 内部更容易理解的一种结构。

    例如它会知道:

    我要查 user 表
    我要查 name 字段
    查询条件是 id = 1
    这是一个 SELECT 查询


    4. 执行 SQL:预处理器、优化器、执行器

    解析完成之后,SQL 还不会马上去磁盘查数据,而是进入执行 SQL 的流程。

    这里分为三个阶段:


    第一阶段:预处理器

    预处理器主要检查两个问题。

    1. 表是否存在

    比如:

    select * from student;

    如果数据库中根本没有 student 表,就会在这个阶段报错。

    2. 字段是否存在

    比如:

    select age from user;

    如果 user 表中没有 age 字段,也会报错。

    3. 展开 select *

    例如:

    select * from user;

    假设 user 表有这些字段:

    id, name, age, phone

    那么 MySQL 内部会把 * 展开成:

    select id, name, age, phone from user;

    所以 select * 实际上不是直接查一个星号,而是查所有字段。


    第二阶段:优化器

    优化器的作用是:

    决定这条 SQL 用什么方式执行成本最低。

    比如有这样一条 SQL:

    select * from user where id = 1 and name = 'Tom';

    如果 id 上有索引,name 上也有索引,那么 MySQL 要决定:

    是走 id 索引?
    还是走 name 索引?
    还是全表扫描?

    优化器会根据统计信息估算成本,选择一个它认为最优的执行方案。

    这个方案就叫 执行计划。

    你可以把优化器理解为:

    SQL 的路线规划器。

    就像导航软件会选择一条预计最快的路线,优化器会选择一条预计成本最低的查询路径。


    第三阶段:执行器

    执行器拿到执行计划后,真正开始执行 SQL。

    但是执行器本身不直接操作磁盘文件。

    它会通过接口调用下面的 存储引擎。

    比如 InnoDB、MyISAM 等。

    图中有一句:

    调用 API 接口

    意思就是:

    Server 层的执行器通过统一接口,让存储引擎去读数据。

    例如执行:

    select * from user where id = 1;

    如果优化器决定走主键索引,那么执行器会告诉 InnoDB:

    请根据主键 id = 1 帮我找这条记录

    InnoDB 找到数据后返回给执行器。

    执行器再把结果返回给连接器,最后返回给客户端。


    5. 查询缓存记录:把结果放入缓存

    如果是 MySQL 8.0 之前,并且开启了查询缓存,那么查询结果返回前,可能会把结果存入查询缓存。

    这样下次执行完全一样的 SQL 时,可以直接从缓存返回。

    不过再次强调:

    MySQL 8.0 已经删除查询缓存,所以现在一般不重点考虑这个模块。


    整体流程总结

    一条 SQL 查询语句的执行过程可以总结成:

    客户端发送 SQL

    连接器建立连接、校验身份、检查权限

    查询缓存,命中则直接返回

    解析器进行词法分析、语法分析,生成语法树

    预处理器检查表和字段是否存在,展开 select *

    优化器生成执行计划

    执行器根据执行计划调用存储引擎

    存储引擎读取数据

    执行器返回结果

    客户端收到结果

    更简单地记:

    连接器 → 查询缓存 → 解析器 → 预处理器 → 优化器 → 执行器 → 存储引擎


    Server 层和存储引擎层的区别

    图中上半部分是 Server 层,下半部分是 存储引擎层。

    Server 层负责什么?

    主要负责 MySQL 的通用功能:

    连接管理
    权限校验
    SQL 解析
    SQL 优化
    SQL 执行
    函数、存储过程、触发器、视图等

    不管你用的是 InnoDB 还是 MyISAM,Server 层都一样。


    存储引擎层负责什么?

    存储引擎层负责真正的数据存储和读取。

    比如:

    数据怎么存
    索引怎么组织
    事务怎么实现
    锁怎么加
    数据页怎么读写

    InnoDB 是最常用的存储引擎,它支持:

    事务
    行锁
    MVCC
    Redo Log
    Undo Log
    B+ 树索引


    举个完整例子

    执行:

    select * from user where id = 10;

    过程是:

  • 客户端把 SQL 发给 MySQL;
  • 连接器确认用户身份和权限;
  • 查询缓存检查是否有相同 SQL 的结果;
  • 解析器分析 SQL,知道这是查询 user 表,条件是 id = 10;
  • 预处理器检查 user 表是否存在,id 字段是否存在,并把 * 展开成所有字段;
  • 优化器发现 id 是主键索引,于是决定走主键索引;
  • 执行器调用 InnoDB;
  • InnoDB 根据 B+ 树索引找到 id = 10 的记录;
  • InnoDB 把记录返回给执行器;
  • 执行器把结果返回给客户端。

  • 面试时可以这样回答:

    一条 SQL 查询语句首先经过连接器建立连接并校验权限,然后查看查询缓存,如果没有命中,就由解析器进行词法分析和语法分析生成语法树。接着进入预处理阶段,检查表和字段是否存在,并展开 select *。之后优化器根据成本选择最优执行计划,最后执行器按照执行计划调用存储引擎接口读取数据,并将结果返回给客户端。MySQL 8.0 已经删除了查询缓存模块。

    赞(0)
    未经允许不得转载:171主机测评 » 【Mysql】执行SQL查询语句的过程
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址