面试官:你来讲讲一条查询语句的具体执行过程

2024-03-18 02:30

本文主要是介绍面试官:你来讲讲一条查询语句的具体执行过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

每天早上七点三十,准时推送干货

对于一个开发工程师来说,了解一下 MySQL 是如何执行一条查询语句的,不是一件坏事,阿粉带你来瞅瞅它是怎么执行的

一条看似非常简单的查询语句:

select * from T where id=1;

然后 MySQL 就返回给了你结果,但是里面具体是如何执行的呢?

别急,听阿粉慢慢跟你说

首先咱们先来看一张图,接下来的过程都是基于这张图来讲的:


连接器

当客户端连接 MySQL 时,会发出连接请求到连接器,连接器此时就会去验证这个连接的账号密码

  • 如果账号或者密码不正确,客户端就会收到一个 Access denied for user 的错误,之后此次连接结束

  • 账号密码正确,连接器会到权限表里面查询出该账号所拥有的权限,之后这个连接里面的权限判断,都是以此时读到的权限为根据

所以你知道为什么更改了一个账号的权限之后,一定要断开再重连才有效吧~

在实际中肯定有这样的情况,就是一个连接建立之后,但是我没有执行什么操作,那么就可以说这个连接处于空闲状态( sleep )

如果长时间都没有什么操作的话,连接器就会选择把它断开,这个时间是由 wait_timeout 来控制的,默认值是 8 小时

连接都被断开了,如果此时客户端再次发送请求想要进行一些操作的话,那就需要重新建立连接才能往下走

在数据库中有两种连接:

  • 短连接:每次执行完很少的几次查询就断开连接,下次想查询时,就要重新建立一个

  • 长连接:如果客户端持续有请求,那就一直使用同一个连接

建立连接是比较麻烦的,首先要发送请求吧,发送了请求要去验证账号密码吧,验证完了要去看你所拥有的权限吧,所以在使用过程中,尽量使用长连接

但是使用长连接又有新的问题:有时候,你会发现 MySQL 占用内存,因为是长连接嘛,所以它会在断开的时候才将资源释放掉。

这个时候可以考虑下面两种方案:

  • 定期断开长连接

  • 如果使用的是 MySQL 5.7 或者更高版本,可以在每次执行一个比较大的操作之后,通过执行 mysql_reset_connection 来重新初始化连接资源,这个过程不需要重新连接和权限验证

分析器

连接器这一关是过来了,接下来就是去查询缓存

首先看缓存里面有没有,如果有呢,那就没有必要向下走,直接返回给客户端结果就可以了

如果缓存中没有的话,那就去分析器

但是聪明的你肯定发现了,我的小标题并不是缓存,而是分析器,为啥呢?

因为查询缓存的失效非常频繁,只要有对一个表的更新,那在这个表上的所有查询缓存都会被清空。所以就会导致 MySQL 费劲吧啦的把缓存给建立起来了,结果呢还没怎么用,一个更新操作,给弄没了

所以 MySQL 8.0 版本直接将查询缓存的整块功能都给删掉了,那么在这里也不细说,免得奇怪的知识增加


分析器首先会进行"词法分析",词法分析就是 select * from T where id=1; ,它会将 select 识别出来,哦,这是一个查询语句,接下来会将 T 也识别出来,哦,你是想要在这个表中做查询,然后将 where 后面的条件也识别出来,原来我需要去查找这些内容

OK ,“词法分析”之后,接下来是“语法分析”,语法分析主要就是分析输入的 SQL 语句合不合法

就比如英语里面的语法 “我用 is , 你用 are ”这种,如果不对肯定是不可以的,语法分析之后发现你的 SQL 语句不符合规则,就会收到 You hava an error in your SQL syntax 的错误提示

优化器

经过分析器分析之后, MySQL 就知道你要的是什么了

但是就像条条大路通罗马一样,看似是一条简单的 SQL 查询语句,有可能有好多条执行路径可以走,比如说要查询的表里面有多个索引,我使用哪儿个索引效率会比较高呀;多表联查的时候,我先关联哪儿个表效率会比较高呀

像这种就是优化器需要做的事情

执行器

优化器做完优化之后,就到了执行器

执行器就是要去执行语句了嘛,那我肯定要看看对于要查询的表 T 有没有查询权限,如果没有直接就拒绝,这没啥说的 如果有的话,那就会这样(在这里以 InnoDB 为例):

  • 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 的值是不是 10 ,如果不是就跳过,如果是那就放在结果集中;

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

  • 执行器将上述遍历过程中所有满足条件的行,组成记录集返回给客户端

至此,语句执行结束

存储引擎

存储引擎,一听名字大概就能知道,它负责的是对数据的存储和提取

关于存储引擎这块,最熟悉的应该就是 InnoDB 了,毕竟从 MySQL 5.5.5 版本开始它就成为了默认的存储引擎

举个栗子

OK ,到这里你可能就比较了解了,但是阿粉这个暖男,为了让你更加的理解,还准备了个栗子,咱们来瞅瞅:

select * from T where `name` = '阿粉' and age = '18' ;

还记得吗?MySQL 首先会怎么做?

  • 通过连接器查询当前执行者的角色是否有权限,进行查询。如果有的话,就继续往下走,如果没有的话,抱歉,哪怕是你貌美如花,也要拒绝掉,同时甩你一个 Access denied for user  的错误信息

  • 接下来就是分析器来分析语句了,嗯,你这个语句写的没啥问题,继续向下执行吧

  • 此时来到了优化器,优化器就想,这条执行语句,有两种执行方案啊:

    • 先查询表 T 中姓名为 阿粉 的,然后再判断他年龄是不是 18 岁

    • 先查询表 T 中年龄为 18 岁的所有人,然后再从里面找到姓名为 阿粉

  • 等优化器决定选择哪个方案之后,执行器就去执行了。然后返回给客户端结果

完美结束


参考

极客时间--《MySQL 实战 45 讲》

MySQL 是如何执行一条查询语句的,你 get 了吗?

最后说两句(求关注)

最近大家应该发现微信公众号信息流改版了吧,再也不是按照时间顺序展示了。这就对阿粉这样的坚持的原创小号主,可以说非常打击,阅读量直线下降,正反馈持续减弱。

所以看完文章,哥哥姐姐们给阿粉来个在看吧,让阿粉拥有更加大的动力,写出更好的文章,拒绝白嫖,来点正反馈呗~。

如果想在第一时间收到阿粉的文章,不被公号的信息流影响,那么可以给Java极客技术设为一个星标

最后感谢各位的阅读,才疏学浅,难免存在纰漏,如果你发现错误的地方,由于本号没有留言功能,还请你在后台留言指出,我对其加以修改。

最后谢谢大家支持~

最最后,重要的事再说一篇~

快来关注我呀~
快来关注我呀~
快来关注我呀~

< END >

如果大家喜欢我们的文章,欢迎大家转发,点击在看让更多的人看到。也欢迎大家热爱技术和学习的朋友加入的我们的知识星球当中,我们共同成长,进步。

这篇关于面试官:你来讲讲一条查询语句的具体执行过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/820915

相关文章

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

批量导入txt数据到的redis过程

《批量导入txt数据到的redis过程》用户通过将Redis命令逐行写入txt文件,利用管道模式运行客户端,成功执行批量删除以Product*匹配的Key操作,提高了数据清理效率... 目录批量导入txt数据到Redisjs把redis命令按一条 一行写到txt中管道命令运行redis客户端成功了批量删除k

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Win10安装Maven与环境变量配置过程

《Win10安装Maven与环境变量配置过程》本文介绍Maven的安装与配置方法,涵盖下载、环境变量设置、本地仓库及镜像配置,指导如何在IDEA中正确配置Maven,适用于Java及其他语言项目的构建... 目录Maven 是什么?一、下载二、安装三、配置环境四、验证测试五、配置本地仓库六、配置国内镜像地址

Oracle查询表结构建表语句索引等方式

《Oracle查询表结构建表语句索引等方式》使用USER_TAB_COLUMNS查询表结构可避免系统隐藏字段(如LISTUSER的CLOB与VARCHAR2同名字段),这些字段可能为dbms_lob.... 目录oracle查询表结构建表语句索引1.用“USER_TAB_COLUMNS”查询表结构2.用“a

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一