当前位置: 首页 > 科技观察

面试官:说说查询语句的具体执行过程

时间:2023-03-23 01:47:58 科技观察

对于开发工程师来说,了解MySQL是如何执行查询语句并不是一件坏事。阿粉带你看看它是如何工作的执行一条看似很简单的查询语句:select*fromTwhereid=1;然后MySQL会把结果返回给你,但是它是怎么执行的呢?别着急,听阿芬慢慢告诉你。首先,让我们先走。看一张图,下面的流程是基于这张图:当客户端连接MySQL时,connector会向connector发送连接请求,connector此时会验证连接的账号密码。如果帐号或密码不正确,客户端将收到用户错误拒绝访问。连接结束,账号密码正确后,connector会查询权限表,找出账号的权限。权限的判断是根据此时读取到的权限,所以在知道为什么更改某个账号的权限后,必须断开重连才能生效~实际中肯定有这样一种情况,也就是connectionisestablished之后,但是我没有进行任何操作,那么可以说连接是空闲的(休眠)。如果长时间没有操作,连接器会选择断开连接。这个时间是由wait_timeout控制的,默认值是8小时,连接已经断开。如果此时客户端再次发送请求,想要进行一些操作,那么就需要重新建立连接才能往下走。数据库中有两种连接:短连接:每次执行几次查询后,连接就断开了。下次要查询时,需要重新建立长连接:如果客户端不断有请求,用同一个连接建立连接很麻烦。首先,发送Request,发送一个验证账号密码的请求,验证之后需要检查自己有哪些权限,所以在使用的过程中,尝试使用长连接但是长连接又出现了新的问题:有时候,你会发现MySQL占用内存,因为是长连接,所以只有在断开连接的时候才会释放资源。这时可以考虑以下两种解决方案:定期断开长连接。如果您使用的是MySQL5.7或更高版本,则可以通过在每次大型操作后执行mysql_reset_connection来重新初始化连接资源。这个过程不需要重连和权限验证analyzerconnector就结束了。接下来就是先查询缓存,看看缓存中有没有。如果有,那么就不用再往下走,直接把结果返回给客户端即可。如果缓存里没有,那就去分析器,但是你一定发现了,我的字幕不是缓存,而是分析器。为什么?因为querycache失效的频率非常高,只要有一个表Update,这个表上的所有querycache都会被清空。所以会导致MySQL努力构建缓存,但是结果用处不大,丢失了一个更新操作,所以MySQL8.0版本直接删除了querycache的整个功能,那我就不细说了这里,为了不增加奇怪的知识,分析器会先进行“词法分析”,词法分析就是select*fromTwhereid=1;,它会识别select,哦,这是一条查询语句,接下来,T会还要识别,哦,你要对这个表做一个查询,然后识别where后面的条件,所以我需要找到这些内容OK,“lexicalanalysis”之后,下一步是“Grammaranalysis”,语法分析主要是分析输入的SQL语句是否合法,比如英文的语法“Iuseis,youuseare”,如果错了,肯定是不允许的。经过语法分析,你可以发现你的SQL语句不符合规则,你会收到一条错误信息你的SQL语法有错误。优化器经过分析器分析后,MySQL就知道你要什么了,但似乎条条大路通罗马。一个简单的SQL查询语句可能有很多执行路径。比如要查询的表有多个索引。我使用哪个索引会更有效率;哪个表会更有效率?这就是优化器需要做的事情。executor优化器完成优化后,再转到executor。执行者将执行该语句。然后我必须查看查询。表T有查询权限吗?如果没有,将直接被拒绝。如果有,那么会是这样(这里以InnoDB为例):调用InnoDB引擎接口去取这张表的第一行,判断ID的值是不是10?如果没有,请跳过它。如果是,则放入结果集中;调用引擎接口获取“下一行”;重复相同的判断逻辑,直到上述遍历过程中执行完表的最后一行,所有满足条件的行组成一个记录集返回给客户端。至此,语句的执行结束。Storageengine存储引擎,看名字就知道了。它负责存储和提取数据。关于存储引擎,大家最熟悉的应该就是InnoDB了,毕竟从MySQL5.5.5开始它就成为了默认的存储引擎或许你有更好的理解,但是阿芬暖男准备了一个栗子让你更好的理解。我们来看一下:select*fromTwhere`name`='AFen'andage='18';记住?MySQL首先会做什么?使用连接器检查当前执行者的角色是否有权限。如果你想拒绝它,同时抛给你一个Accessdeniedforuser的错误信息。下一步是分析器来分析语句。嗯,你的说法没有错。继续执行。这个时候你就来到了优化器,优化器试想一下,这个执行语句有两个执行计划:首先查询T表中名字叫阿芬的人,然后判断他的年龄是否是18岁;先查询表T中所有年龄为18岁的人,然后优化器决定选择哪个计划后,由执行器执行。然后将结果返回给客户端