SQL语句在MySQL中是如何被执行的?

前言

相信大家用了这么久的MySQL,一定很好奇自己写的SQL是如何执行并返回结果的,今天我们就来一层一层剥开MySQL这颗洋葱。

首先我们通过一张图来了解下整个过程,然后再开始一步一步解析。

第一步:客户端发送SQL语句到MySQL服务端

假如项目中用到了Mybatis来操作数据库,那么Mybatis就会通过JDBC来连接数据库,并发送语句给数据库,因为一般运行Web后台服务的机器和MySQL服务都是物理上隔开的,是一个分布式架构,所以需要通过网络来访问,JDBC采用TCP连接的方式与MySQL服务端进行通信,通信的内容包括发送语句、接收执行结果等。虽然TCP是全双工的,但是Mysql的TCP是半双工的,这意味着同一时刻要么客户端在发送数据,要么服务端在发送数据。

第二步:验证连接合法性

JDBC与数据库建立的连接的时候,会要求输入用户名和密码,Mysql需要验证用户名是否存在,密码是否正确。验证通过后,再根据mysql.user表中的host字段来验证客户端IP是否是允许的IP,这个host字段相当于一个白名单。

前面的合法性都通过后,JDBC才会发送实际的SQL语句给MySQL服务端。

第三步:查询缓存

像上面这种SELECT语句,MySQL服务端收到这个SQL时,如果开启了查询缓存,就会根据SQL语句在查询缓存中查找,查找成功就直接返回查询缓存中的结果给客户端,而不会执行下面这些操作。

请注意,这里的查找方式是根据SQL语句进行hash运算,只要SQL中有一个字节不同都不会命中缓存。

第四步:语法解析和预处理

当查询缓存没有命中时,才会开始进行语法解析和预处理。语法解析就像一个编译程序一样,根据语句生成语法树,并检查语法树中的关键字是否正确,顺序是否正确,引号是否前后匹配等。

经过语法解析后,预处理就会检查sql中的表、列是否存在,列名是否有歧义等,同时预处理还会对SQL进行权限认证,比如该用户是否有SELECT权限、INSERT权限…, 是否有对应数据库的权限、表的权限等等。

第五步:查询优化

查询优化主要分为两部分,一是静态优化二是动态优化。静态优化可以把语句中一些where条件进行等价交换,比如:WHERE 1=1 AND a > 2将被替换为WHERE a > 2;静态优化不依赖sql语句的具体值,就像Java静态编译器的语法糖一样。

动态优化:因为动态优化以页为最小单元来评估成本,所以需要分析SQL语句所对应的表的索引页或者数据页的数量,以此来确定是走索引还是全表扫描。这些信息都是通过存储引擎来获得的,所以如果存储引擎给出的结果不精确,那么查询优化的执行计划可能就不是最优的。

因为一条sql可以选择的执行方式有很多种,比如一张表里有多个索引,SQL语句涉及多个表的连接查询,那么得到上述信息后,就需要评估使用哪些索引、哪个表关联的顺序是最优的,并以此来生成一条执行计划。这部分也是Mysql服务层最复杂的地方,因为需要考量的因素有很多,这里笔者只是列出了一小部分。

第六步:调用存储引擎执行

其实在MySQL中,真正决定怎么存储数据和查询数据的组件是存储引擎。所以在第五步中得到了执行计划后,MySQL会调用表所对应的存储引擎的API,来执行真正的查询。Mysql定义了一系列存储引擎接口,来让编写存储引擎的人来实现,所以只要符合接口定义的存储引擎都是可以放入MySQL中去使用的。其中使用最广泛的引擎莫过于InnoDB,InnoDB是一个支持事务、支持崩溃快速恢复的高性能存储引擎。

Mysql服务层和存储引擎层最大的区别是:服务层实现了一些不依赖于具体存储引擎的通用操作,比如上面的连接验证、SQL验证这些。而存储引擎则完成具体的查询存储操作,所以好的存储引擎是Mysql的关键。

第七步:将结果返回给客户端

容易想到的一种方式是MySQL服务端先把查询结果缓存到内存中,然后再一次性发送给客户端,可实际上不是这样的。实际是拿到符合条件的第一条数据就返回给客户端,这是一个增量过程。这样做的原因,是可以缓解服务端的内存压力。

如果开启了查询缓存,并且语句是UPDATE、DELETE、INSERT之类的操作,那么这个时候也会更新查询缓存。

总结

在整个过程中,最复杂的部分是第五步的查询优化和第六步中具体的存储引擎,实现细节是造就了MySQL长盛不衰的原因。如果想要优化MySQL的性能,有几步可以优化:

客户端使用连接池,这样可以让连接复用,因为MySQL每接收一个连接都要用一个线程去处理,和其他Web服务器的连接池解决的问题一样,这里也可以解决。

查询缓存虽然在查询时可以避免很多后续操作的成本,但是维护它的成本也挺高的,因为每次UPDATE、DELETE、INSERT都需要互斥地更新对应表的查询缓存,这会成为MySQL的可扩展性瓶颈。根据阿姆达尔定律,决定一个系统能否水平扩展的是程序串行的部分。在MySQL8.0以上版本中,默认禁用了查询缓存。所以除非你能确定查询缓存确实对吞吐量有帮助,否则禁用查询缓存是个好建议。

默认情况下,客户端在第七步的接收过程中,其实是在自己的内存里缓存了全部结果之后,才会解除阻塞,这些会创建很多对象,当并发增高时,可能会引起JVM的OOM。所以这里可以改为每次只接收部分数据,处理完后再接收部分。但这里服务端对于资源都是持有状态,所以是一个空间和时间上的权衡。

如果有必要,你可以干涉第五步的查询优化过程,MySQL提供一些hint语句,比如强制走规定的关联表顺序或者强制使用某些索引。但是大多数情况下,请不要以为自己比查询优化器更聪明,使用推荐的方案可能更好。

设计一个好的索引对于查询的性能影响非常之大,所以对于使用关系型数据库来说,索引设计是非常重要的一环。

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/231883.html<

(0)
管理的头像管理
上一篇2025-04-19 22:03
下一篇 2025-04-19 22:04

相关推荐

  • 站群服务器如何批量管理更高效,有哪些管理技巧?

    站群服务器批量管理想提效,自动化是唯一出路,通过统一配置管理工具与面板系统,结合服务商提供的底层基础设施支持,能将运维效率提升数倍,批量管理的核心痛点与解决思路多台站群服务器分散管理,最常见的问题就是重复劳动,每次软件更新、配置修改、安全加固,都需要逐台登录操作,不仅耗时,还容易漏掉某台机器,更头疼的是,一旦某……

    2026-07-27
    0
  • 服务器磁盘IO过高如何优化?,磁盘IO过高的原因有哪些?

    服务器磁盘IO过高,核心优化路径是“先定位、再分流、后升级”,你需要通过系统工具精确判断究竟是应用程序、日志策略还是硬件瓶颈导致,然后针对性地从代码、缓存、存储架构和硬件选型四个层面下手,其中选择持有持牌自营机房和增值电信业务经营许可证的服务商,能从根本上保障底层IO稳定性,定位IO瓶颈:动手优化的第一步盲目优……

    2026-07-27
    0
  • 跨境网站访问延迟高怎么解决,网站访问慢的原因是什么?

    跨境网站访问延迟高的核心解决思路在于多维度优化网络路径,包括使用全球CDN加速、选择靠近目标区域的优质IDC机房、调整传输协议以及精简应用层资源,其中服务商的基础设施质量直接决定优化上限,为什么跨境访问延迟高?三大核心因素物理距离与光速限制数据包在海底光缆中的传输速度受限于介质,从中国到美国西海岸的物理往返时间……

    2026-07-27
    0
  • 站群服务器到底是什么意思,怎么选择比较好

    站群服务器就是一台拥有多个独立IP地址、专门用于托管和管理多个网站的高性能服务器,其核心价值在于通过独立IP降低网站间的关联风险,并提升搜索引擎优化效果,站群服务器的工作原理与适用场景站群服务器本质上是将一台物理服务器通过虚拟化或直接配置的方式,分配给多个独立IP地址,每个IP对应一个独立的网站,这些网站共享服……

    2026-07-27
    0
  • 高防服务器误封正常流量如何调整,怎么解决?

    高防服务器误封正常流量,核心调整思路是从“一刀切”转向“精细化”——通过分析业务特征,调整防护阈值、配置白名单和启用智能学习模式,让防护系统学会区分真假流量,为什么会误封正常流量误封主要源于防护策略的通用化,高防服务器通常默认启用严格防护规则,当流量特征与攻击特征库部分匹配时,就会被拦截,据行业安全白皮书指出……

    2026-07-27
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注