一条SQL语句执行的过程

Mysql 逻辑架构

  • Server 层负责建立连接、分析和执行 SQL

  • 存储引擎层负责数据的存储和提取。

  • 大概过程

    • 连接器连接

    • 查询缓存

    • 解析SQL

    • 执行SQL

具体过程:

  连接
  1. 连接器

          上述命令可以查询服务连接个数还有当前状态

    1. 作用:跟客户端建立连接、获取权限、维持和管理连接

    2. 一般的命令格式: mysql -h$ip -P$port -u$user -p

    3. 在完成经典的TCP握手后,连接器就要开始认证你的身份,这个时候用的就是你输入的用户名和密码

      • 正确:查出你拥有的权限。之后,这个连接里面的权限判断逻辑,都将依赖于此时读到的权限。

      • 错误:Access denied for user 客户端程序结束执行

    4. 连接完成后,如果你没有后续的动作,这个连接就处于空闲状态

    5. 客户端如果太长时间没动静,连接器就会自动将它断开。这个时间是由参数wait_timeout控制的,默认值是8小时。

      • 长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。

      • 短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。

      • 尽量使用长连接。

        • 出现的问题:全部使用长连接,有些时候MySQL占用内存涨得特别快,在执行过程中临时使用的内存是管理在连接对象里面的,这些资源会在连接断开的时候才释放。如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是MySQL异常重启了。

        • 解决方案:

          • 定期断开长连接。

          • 如果你用的是MySQL 5.7或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection来重新初始化连接资源。

    6. 如果一个用户已经建立了连接,即使管理员中途修改了该用户的权限,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。

  查询缓存
  1. 查询缓存

    1. MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以key-value对的形式,被直接缓存在内存中。

    2. key是查询的语句,value是查询的结果。

    3. 如果查询命中缓存,MySQL不需要执行后面的复杂操作,就可以直接返回结果,这个效率会很高。

    4. 查询缓存往往弊大于利

      • 查询缓存的失效非常频繁

        • 有对一个表的更新,这个表上所有的查询缓存都会被清空

      • 查询缓存的命中率会非常低

      • MySQL也提供了这种“按需使用”的方式,将参数query_cache_type设置成DEMAND对于默认的SQL语句都不使用查询缓存。

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

  解析SQL
  1. 分析器

    1. 知道你要做什么,因此需要对SQL语句做解析。

    2. 分析器先会做“词法分析”:MySQL 会根据你输入的字符串识别出关键字出来。

    3. 再做“语法分析”:语法解析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。

      • 错误提示:You have an error in your SQL syntax

      • 一般语法错误会提示第一个出现错误的位置,所以你要关注的是紧接“use near”的内容。

    4. 构建的 SQL 语法树

  执行SQL
  1. 预处理器

    1. 检查 SQL 查询语句中的表或者字段是否存在。

  2. 优化器

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

    2. 执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。

  3. 执行器

    1. 开始执行语句

      • 先判断一下你对这个表T有没有执行查询的权限。

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

        • 慢查询日志中看到一个rows_examined的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。

        • 在有些场景下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟rows_examined并不是完全相同的。

    2. 在执行的过程中,执行器就会和存储引擎交互了,交互是以记录为单位的。

    3. 执行过程

      • 主键索引查询

        • 让存储引擎定位符合条件的第一条记录。

      • 全表扫描

        • 让存储引擎读取表中的第一条记录。

      • 索引下推

        • 将 Server 层部分负责的事情,交给存储引擎层去处理了

        • 减少二级索引在查询时的回表操作,提高查询的效率。

  • 44
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值