【MySQL系列】一条查询sql如何执行

138 阅读5分钟

SQL的执行顺序是怎样的?

  • sql语句顺序:select distinct ... from table where ... group by ...having ... order by ... limit ...
  • 执行顺序:①from ②where ③group by ④having ⑤select ⑥distinct ⑦order by ⑧limit
  • 执行顺序:从表中查询数据,先经过where进行筛选出有价值的数据,对这些有价值的数据进行分组,分组之后进行having进一步筛选。select进行列筛选,查询出需要的字段,distinct进行去重,order by 进行排序,最后分页输出指定条数。
  • 说明点:分组函数不能用在分组函数之后:如 select * from table where s>min(ss); 虽然没有写group by,那么默认分成了一组。因为where在group by之前执行的,所以不能这样写。

mysql的连接过程

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ce430ae81d644baf82144406b4b729b5~tplv-k3u1fbpfcp-zoom-1.image

  • *MySQL驱动:**java系统在执行SQL语句时,需要MySQL驱动帮我们建立连接到Mysql服务器。SQL语句请求一次就会建立一次连接,每次建立连接的过程是基于TCP/IP协议的。为避免频繁的创建和销毁连接而带来性能的开销,就引入了数据库连接池来管理连接。数据库连接池就是维护一定的连接数,在使用时就去池子里获取,用完再放回,而当连接数不够时,池子会创建新的连接。总之,我们不需要关心如何连接及如何管理连接的。
  • *MySQL数据库:**在处理并发的数据时是如何处理的呢?MySQL 的架构体系中也是基于数据库连接池来管理各连接的。

那么在整个连接的过程,这个连接器是用于连接处理、权限认证与安全性等功能。每个服务器连接都会在服务器进程中拥有一个线程,这个连接的查询只会在这个单独的线程中执行。该线程只能轮流在某个CPU核心或CPU中进行。

MySQL数据库架构体系

SQL语句请求时建立的每个连接,其实都是由一个个的线程来处理的,然后线程就交由server层来处理。

大多数的MySQL的核心服务功能都在这一层,包含了查询解析、分析、优化、缓存以及所有的内置函数,如日期、时间、加密,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/72690e5f3fc84ad88832eb073845ae63~tplv-k3u1fbpfcp-zoom-1.image

查询缓存

对于select语句,在解析查询之前,服务器会先检查查询缓存。如果能够在其中找到对应的查询,服务器就不必再执行查询解析、优化和执行的整个过程,而是直接返回查询缓存中的结果集。

但在mysql8.0版本后缓存功能被取消。MySQL服务器团队有一篇关于此的详细博客,其中Matt Lord说:

尽管MySQL Query Cache旨在提高性能,但它存在严重的可伸缩性问题,并且很容易成为严重的瓶颈。 自MySQL 5.6(2013)以来,默认情况下已禁用查询缓存,因为众所周知,它不能与多核计算机上在高吞吐量工作负载情况下进行扩展。 我们考虑了可以对查询缓存进行哪些改进,以及我们可以进行的优化,这些优化可以改善所有工作负载

分析器

解析器通过关键字将SQL语句进行解析,并生成对应的解析树。MySQL解析器将使用MySQL语法规则验证和解析查询。

预处理器则根据一些MySQL规则进行进一步检查解析书是否合法,例如检查数据表和数据列是否存在,还会解析名字和别名,看看它们是否有歧义。

优化器

优化器将解析树转换成执行计划,比如选择哪个索引、先查询哪个表。

打个比喻,我们要去某个目的地,有好几条路径都可以到达,要选择最优的路径来执行。那优化器就扮演选择最优解的角色,几条路就是多个执行计划。但在选择的过程中是要耗费时间的。如果在sql语句在执行过程中将执行计划缓存,则在相似语句再次出现时,服务器就可以直接使用缓存的执行计划了,从而直接跳过生成执行计划的过程,从而提升查询效率。

执行器

担任一个执行的角色,将一系列的执行计划通过调用存储引擎的API接口来完成SQL的执行。

存储引擎层

存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。

服务器通过API与存储引擎进行通信。这些接口屏蔽了不同存储引擎之间的差异,使得这些差异对上层的查询过程透明。存储引擎API包含了几十个底层函数,用于执行诸如"开始一个事务"或"根据主键提取一行记录"等操作。存储引擎并不会解析sql,不同的存储引擎之间也不会相互通信,而只是简单地响应上层服务器的请求。

用哪一种引擎可以灵活选择,一个数据库中多个表可以使用不同引擎以满足各种性能和实际需求,使用合适的存储引擎,将会提高整个数据库的性能 。

推荐文章

MySQL探秘(二):SQL语句执行过程详解

重学MySQL:一条 SQL是怎么执行的?历经哪些过程?

MySQL 三万字精华总结 + 面试100 问,和面试官扯皮绰绰有余(收藏系列)