Mysql(一)查询Sql是如何执行的

Hello,大家好我是极客涛😎,我最近在整理Mysql相关的知识点,所以准备开启一个Mysql的主线任务,大概耗时3周左右,整个节奏还是由浅入深,主要包括Mysql的架构、事务实现、索引组织形式、SQL优化、日志系统、锁、主从架构、无锁变更、最佳实践等等。大家可以随着我的这个路线,一起沉淀沉淀,如何检验自己的学习成果呢,刷面试题,遇到不清楚的在往深里研究。好了,那我们开始~

引言

我们知道Mysql是一个数据库系统,提供了对数据的增删改查API,我们通过一条条简单的SQL就可以实现对系统的各种操作,为了更容易理解,我们按照从整体到局部的思路,先鸟瞰Mysql整体的架构,然后再对每个细节深入研究,所以今天我们通过一条查询SQL的执行流程,看一看Mysql的应用架构是如何组成的。

本文结构
请添加图片描述

阅读体验

📚 全文字数 : 4k+
⏳ 阅读时长 : 6min

Mysql的应用架构

Mysql的应用架构遵循了职责单一、能力分层、插件化的原则。整体上看,Mysql主要分为服务层和引擎层:

服务层:Mysql的通用能力层,负责对外(客户端)暴露端口、解析SQL语法、执行SQL优化、通过调用引擎层的API对整个查询过程进行API调用的编排。

引擎层:引擎层负责对数据的存储和读取,并通过API将能力暴露给服务层使用。Mysql支持不同的存储引擎通过插件的方式接入Mysql的服务层,不同的存储引擎适用于不同的使用场景,如Memory、InnoDB、MySAM。

再进行细分的话,服务层又包括:连接器、查询缓存、分析器、优化器、执行器。
请添加图片描述

连接器

不管Mysql内部如何运行,都需要有一个与外界进行交互的桥梁,连接器就起到了桥梁的作用。连接器是Mysql的统一门面,负责与客户端建立会话连接、进行用户认证、查询用户权限、维持和管理会话连接。

mysql -h$ip -P$oprt -u$username -p$password

当我们执行mysql的连接命令时,通过ip + port 定位到是哪个Mysql服务,经过TCP握手之后,连接器和客户端就建立了会话连接,然后这条命令就来了连接器。连接器首先通过 -u-p 参数对本次请求进行认证操作,验证用户是否在Mysql服务中注册过,密码是否正确,如果认证失败,则直接响应Access denied for user ‘xxx’@‘localhost’ (using password: YES)

认证通过后,连接器则会查询用户的权限列表,判断对该用户是否开放了远程连接权限。Mysql默认只允许本机(localhost)进行连接操作,如果没有远程连接权限直接响应Access denied for user ‘root’@‘%’ to database ‘mysql。如果有远程连接权限,那么本次连接就真正意义上建立完成了。需要注意的是,查询出来的权限列表会一直向下传递,之后对表的权限校验、对操作的权限校验都依赖于这个权限列表。

正是因为先鉴权再建立会话连接,所以即使对当前连接用户的权限进行了修改,也不会立即生效,需要等到下次重新连接时才会生效。

为了提高资源的利用率,当客户端与连接器建立连接之后,如果客户端长时间没有进行任何操作,连接器会自动将这个连接断开(默认是8小时,由wait_timeout参数控制)。

在客户端与服务端的通信中,一般分为长连接短连接长连接就是客户端和服务端建立连接之后会一直保持的这个连接,后续的任意操作不会重建连接,这样避免了每次操作需要重新创建连接的操作,执行速度会快很多。但是连接不释放就意味着对象不能销毁,如果连接数过多的话,可能会导致Mysql服务因内存不足而重启;短连接相反,每次请求都需要重新创建连接,相对来说执行速度会慢一些,但是每次请求完都释放连接和对象,这样消耗的内存资源要大大降低。

从客户端的角度来说,肯定更中意使用长连接,因为可以提高响应速度;从服务端的角度来说,更中意短连接,因为逻辑简单,资源消耗少。那如何中和两个方案的优缺点呢?连接池就顺势而生了,连接池是存在于客户端的,应用程序会在初始化时通过连接池申请若干个长连接,而应用程序内的所有线程共享这个连接池,因为一次请求很快就结束了,这样其它请求来的时候可以复用这个连接,而当某个连接长时间没有被使用时,就将其释放,这样便发挥了长连接和短连接各自的优点。

查询缓存

select * from geektao where id = 2;

通过连接器的认证鉴权之后,就开始进行查询操作了。

首先会看看当前SQL是否已经在查询缓存中存在,查询缓存通过key=value的方式存储SQL及其执行结果,如果存在则直接返回缓存中的执行结果,查询效率大大提高。

但是在实际的生产使用过程中并不建议使用查询缓存,因为生产中被查询的数据往往是不断变化的,这样就会造成缓存一直失效,每次查询完之后还要设置缓存,不仅没有提高查询效率,反而造成额外的开销,使用起来很鸡肋。Mysql8.0版本直接把查询缓存整个模块删掉了,如果版本小于8.0的话可以通过设置query_cache_type=DEMAND关闭查询缓存。

分析器

如果查询缓存关闭或者缓存中没有的话,那么就真真正正的开始解析SQL了。了解编译原理的同学应该知道,作为一个解析器不可缺少的三个功能:词法分析语法分析语义分析

词法分析

词法分析是SQL解析的第一步,它负责将输入的SQL语句字符串分解成一系列的Token(词元)。这些Token是SQL语法的基本组成单元,例如关键字(如SELECTFROM等)、标识符(如表名、列名)、常量值等。但是此时分析器还不知道什么意思,就像我们小时候学字一样,只知道王是王,李是李,并不理解。

语法分析

语法分析阶段,MySQL根据SQL语言的语法规则,将词法分析阶段产生的Token序列转换成一个抽象语法树(Abstract Syntax Tree,AST)。这个过程中,会检查SQL语句是否符合MySQL的语法规则。这时候就像小时候已经开始学造句了,根据特定的语法造句,但是也没有真正理解造出来句子的含义。

语义分析

在语法分析之后,接下来就是语义分析阶段。在这个阶段,MySQL的解析器会检查抽象语法树是否有意义,即检查SQL语句在逻辑上是否正确。这包括识别列名、检查数据类型、确定操作符函数的正确使用、处理别名表达式等。如果在这个阶段发现错误,比如找不到表或列、类型不匹配等,解析器会生成错误信息,此时Mysql才真正理解了这条SQL到底想干啥了。

优化器

经过分析器之后,Mysql就知道我们想干什么了,那下一步是不是就直接去干了。Mysql可没有你想的这么简单,在去干前,Mysql会”思考“如何使用最的查询步骤来查询。

优化器会根据抽象语法树生成执行计划,如果表中有多个索引的话会确定去哪个索引里查询,如果是多表关联查询的话会确定先去哪个表查询再去哪个表查询。总之,优化器会根据不同的情况制定出一个最优的方案,这样Mysql才知道怎么做。

执行器

对执行器来说”器如其名“,前边我们已经通过分析器知道了要做什么通过优化器知道了怎么做而执行器通过执行计划一步步的执行

在执行之前,执行器首先会判断当前用户是否对表有相关的操作权限,而判断的依据就是连接器当时查询出来的权限列表。有同学可能有疑问,到执行器在进行表的权限校验是不是有些晚了,在分析器阶段不是已经知道是要操作哪张表了吗?

确实,在优化器之前会调用precheck验证权限,但是这时候只是进行简单的权限校验,查询的表存不存在、列存不存在,对查询的表有没有操作权限,这些校验都是静态校验。在真正执行时也需要动态校验,因为执行时是运行态,比如该表有个触发器,只能在执行阶段才能进行校验(有一点点像class文件加载过程中的验证阶段)。

执行器阶段的权限校验通过之后,就开始调用执行引擎的接口进行数据读取操作了。

假设不走索引的情况

  1. 打开要查询的表;

  2. 调用执行引擎接口获取第一行记录,判断id是否等于2,等于则保存结果到结果集中;

  3. 调用执行引擎接口获取下一行记录,判断id是否等于2,等于则保存结果到结果集中;

  4. …;

  5. 没有下一行数据,调用结束;

  6. 执行器将结果集返回给客户端。

至此,一条查询语句便执行完毕。

小结

今天主要讲解了Mysql的应用架构,并通过查询SQL为例,对Mysql的每个组件及其作用都进行了描述,相信大家对Mysql整个运行流程有了一个大概的了解,下边给大家留了一些问题加深大家的印象😄。

问题

  1. Mysql的基本架构包括什么,每部分有哪些作用?
  2. select * from geektao where name = 'xx';当表中没有name字段时会怎么样?这是在哪一步判断的?
  3. 为什么要使用连接池?工作原理是什么?一般如何进行参数调优?
  4. 如果Mysql服务端因升配导致连接失效,客户端该如何自动重连?
  5. Mysql哪些阶段会进行权限校验,目的是什么?
  6. select sum(amount) from geektao;sum()是在哪一步计算的?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/339119.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图解大模型分布式并行各种通信原语

背景 在分布式集群上执行大模型任务时候,往往使用到数据并行,流水线并行,张量并行等技术,这些技术本质上也就是对数据进行各种方案的切分,然后放到不同的节点上运算。不同节点在计算的过程中需要对数据分发或者同步等…

python的一种集成开发工具:PyCharm开发工具

一. 简介 本文简单了解两种 python语言所使用的 集成开发环境: PyCharm、vscode。 python语言学习中,可以任意选中这两个集成开发环境的一种就可以。本文先来简单学习 PyCharm开发工具安装与使用。 二. python的一种集成开发工具:PyChar…

实现Redis和数据库数据同步问题(JAVA代码实现)

这里我用到了Redis当中的发布订阅模式实现(JAVA代码实现) 先看图示 下面为代码实现 首先将RedisMessageListenerContainer交给Spring管理. Configuration public class redisConfig {AutowiredRedisConnectionFactory redisConnectionFactory;AutowiredQualifier("car…

Linux线程:线程分离

目录 一、什么是线程分离 1.1pthread_detach 1.2pthread线程库存在的意义 1.3__thread线程的局部存储 1.4系统调用clone 一、什么是线程分离 1.1pthread_detach 默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_joi…

数据标准的制定落地

目录 什么是数据标准 基本定义 目的 数据标准体系分类 从内容层面分类 从管理视角分类 从面向的对象分类 从数据结构的角度分类 数据标准价值 业务价值 技术价值 管理价值 数据标准和数据治理的关系 数据标准在数据治理各项任务中的作用 数据标准与主数据 数据…

车联网安全入门——ICSim模拟器使用

文章目录 车联网安全入门——ISCim模拟器使用介绍主要特点:使用场景: 安装使用捕获can流量candumpcansnifferwiresharkSavvyCAN主要特点:使用场景: 重放can报文cansendSavvyCAN 总结 车联网安全入门——ISCim模拟器使用 &#x1…

LabVIEW步进电机的串口控制方法与实现

本文介绍了在LabVIEW环境中通过串口控制步进电机的方法,涵盖了基本的串口通信原理、硬件连接步骤、LabVIEW编程实现以及注意事项。通过这些方法,用户可以实现对步进电机的精确控制,适用于各种自动化和运动控制应用场景。 步进电机与串口通信…

【刷题(15】普通数组

一 普通数组基础 首先&#xff0c;我们根据下图先了解一下什么是前缀和。 既然我们明白了前缀和是怎么回事&#xff0c;那我们就来看一下我们该怎么输入 先给出答案&#xff0c;然后再给出分析。 答案&#xff1a; for (int i 1; i < n; i ){cin >> a[i];s[i] s…

Pytest框架中用例用例执行常用参数介绍

pytest 支持通过命令行参数来定制测试运行的方式。以下是一些常用的 pytest 执行参数介绍。 学习目录 -q 或 --quiet: 安静模式&#xff0c;只显示进度和摘要 -s : 选项允许在测试的输出中捕获 stdout 和 stderr。 -v : 选项会使 pytest 的输出更加详细。 -k &#xff1a;…

DIYP对接骆驼后台IPTV管理,退出菜单中显示用户名已经网络信息,MAC,剩余天数,套餐名称等

演示&#xff1a;https://url03.ctfile.com/f/1779803-1042599473-4dc000?p8976 (访问密码: 8976) 后台加上EPG&#xff0c;增加一些播放源的动态端口替换。 前台app上&#xff0c;退出菜单中显示用户名已经网络信息&#xff0c;MAC&#xff0c;剩余天数&#xff0c;套餐名称…

QT之常用控件

一个图形化界面当然需要有各种各样的控件&#xff0c;QT也不例外&#xff0c;在QT designer中就有提供各种各样的控件&#xff0c;用以开发图形化界面。 而想使用好一个QT控件&#xff0c;就需要了解这些控件。 QWidget 在QT中&#xff0c;所有控件都继承自 QWidget 类&…

中间件模版引擎

文章目录 中间件1.自定义中间件1&#xff09;全局2&#xff09;局部中间件 2.内置中间件(静态资源目录&#xff09; Art-template1.模板语法1&#xff09;输出2&#xff09;原文输出3&#xff09;条件判断4&#xff09;循环5&#xff09;子模版6&#xff09;模版继承7&#xff…

git远程仓库限额的解决方法——大文件瘦身

Git作为世界上最优秀的分布式版本控制工具&#xff0c;也是优秀的文件管理工具&#xff0c;它赋予了项目成员对项目进行远程协同开发能力&#xff0c;因此受到越来越多的行业从业人员的喜爱。很多优秀的项目管理平台&#xff0c;比如国内的Gitee&#xff0c;国外的Github&#…

Django表单革命:打造安全、高效、用户友好的Web应用

Django表单处理&#xff0c;听起来是不是有点枯燥&#xff1f;别急&#xff0c;阿佑将带你领略Django表单的艺术之美。我们将以轻松幽默的语言&#xff0c;一步步引导你从表单的创建到管理&#xff0c;再到验证和自定义&#xff0c;让你在不知不觉中掌握Django表单的精髓。文章…

SpringMVC:转发和重定向

1. 请求转发和重定向简介 参考该链接第9点 2. forward 返回下一个资源路径&#xff0c;请求转发固定格式&#xff1a;return "forward:资源路径"如 return "forward:/b" 此时为一次请求返回逻辑视图名称 返回逻辑视图不指定方式时都会默认使用请求转发in…

留给“端侧大模型”的时间不多了

端侧大模型&#xff08;Edge AI models&#xff09;&#xff0c;也就是只在设备本地&#xff08;如智能手机、IoT设备、嵌入式系统等&#xff09;运行的大模型&#xff0c;过去一两年来非常流行。 具体表现在&#xff0c;终端设备厂商&#xff0c;如苹果、荣耀、小米、OV等&…

【操作与配置】VS2017与MFC环境配置

【操作与配置】VS2017与MFC环境配置 概述 Visual Studio 是一款强大且多功能的集成开发环境&#xff08;IDE&#xff09;&#xff0c;适用于软件开发人员和团队。使用此应用程序&#xff0c;您可以构建和调试现代Web应用程序&#xff0c;并利用扩展帮助探索几乎任何编程语言。…

重学java 55. 集合 Set接口

我救自己万万次&#xff0c;铮铮劲草&#xff0c;绝不动摇 —— 24.6.2 一、Set集合介绍 Set和Map密切相关的 Map的遍历需要先变成单列集合&#xff0c;只能变成set集合 二、HashSet集合的介绍和使用 1.概述 HashSet是Set接口的实现类 2.特点 a、元素唯一 b、元素无序 c、无索引…

devicemotion 或者 deviceorientation在window.addEventListener 事件中不生效,没有输出内容

问题&#xff1a;devicemotion 或者 deviceorientation 在window.addEventListener 事件中不生效&#xff0c;没有输出内容 原因&#xff1a; 1、必须在Https协议下才可使用 2、必须用户手动点击click事件中调用 &#xff0c;进行权限申请 源码&#xff1a; <!DOCTYPE h…

Docker 部署 mysql 服务

linux用法 Container&#xff08;容器&#xff09;集合成 Services&#xff08;服务&#xff09; 交互集合成 Stack&#xff08;堆栈&#xff09;卸载可能存在的旧版本 sudo apt-get update使apt可以通过HTTPS使用存储库&#xff08;repository&#xff09; sudo apt-get ins…