乐趣区

关于java:面试官你说说一条查询SQL的执行过程

为了了解这个问题,先从 Mysql 的架构说起,对于 Mysql 来说,大抵能够分为 3 层架构。

第一层作为客户端和服务端的连贯,连接器负责解决和客户端的连贯,还有一些权限认证之类。比方客户端通用用户名明码连贯到 Mysql 服务器,还有对于数据库表的执行权限。

第二层是核心层,基本上 Mysql 大部分的外围性能都在这一层,包含查问缓存、解析器、优化器之类,比方 SQL 解析、优化、索引抉择,到最初生成执行打算。

第三层则是存储引擎了,Mysql 通过执行引擎间接调用存储引擎 API 查询数据库中数据。

通过 Mysql 的架构分层,咱们首先就能够很清晰的理解到一个 SQL 的大略的执行过程。

  1. 首先客户端发送申请到服务端,建设连贯。
  2. 服务端先看下查问缓存是否命中,命中就间接返回,否则持续往下执行。
  3. 接着来到解析器,进行语法分析,一些零碎关键字校验,校验语法是否合规。
  4. 而后优化器进行 SQL 优化,比方怎么抉择索引之类,而后生成执行打算。
  5. 最初执行引擎调用存储引擎 API 查问数据,返回后果。

这就是一个很概括性的 SQL 执行过程,接下来,具体到每个步骤具体阐明一下。

查问缓存

如果你翻看 Mysql 的官网文档就会晓得,查问缓存在 5.7.20 版本曾经被弃用,并且 8.0 的版本曾经删除了。为啥要删除,可能感觉太鸡肋了吧。

咱们能够通过命令来查看查问缓存是否可用。

mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+

除此之外,查问缓存还有一些外围参数。更具体的阐明能够参考官网文档。

query_cache_type:是否关上查问缓存,值为 0\1\2,别离对应为 OFF\ON\DEMAND,ON 的话则代表开启查问缓存,然而能够通过 SELECT SQL_NO_CACHE 来手动禁用,DEMAND 则代表只缓存以 SELECT SQL_CACHE 结尾的 SQL 语句。

query_cache_limit:缓存后果大小限度,如果查问后果超过大小则不会被缓存,默认是 1M 大小。

query_cache_size:为查问缓存调配的内存大小,他是 1024 的整数倍。

query_cache_min_res_unit:查问缓存分配内存块的最小单位,默认为 4KB。这是查问缓存分配内存的根本单位,即使比方查问的数据只有 1 个字节,也会依照最小内存单元大小来分配内存空间。

在进行 SQL 解析之前,零碎会判断查问缓存是否关上,如果关上,就拿缓存中的查问和传入的查问比拟,如果齐全一样,就会从缓存中间接返回。

然而须要特地留神的是,无论大小写、空格还是正文,都会影响缓存的命中后果,也就是说必须齐全一样!

比方以下的 SQL 大小写不同、多了空格都无奈命中查问缓存。

select * from user;
SELECT * from user;
select   * from user;

解析器 & 预处理器

如果查问缓存未命中,就会进入失常的 SQL 执行环节。

首先就像咱们失常的业务开发一样,第一步都是对参数的规定校验,Mysql 也一样,解析器会进行词法语法分析,基于语法规定对 SQL 进行校验。

比方关键字是否应用正确啊,或者说关键字程序是不是正确,比如说你把 select 写成了 selctorder by 写成了by order

如果校验 OK,那么就生成一颗“解析树”。

接着预处理器就是进一步根据非法规定生成的解析树进行校验,比方表名、列名是否存在等等。

优化器

如果说解析器和预处理器是咱们业务逻辑的前置校验环节,优化器就是真正的解决业务逻辑的中央。

一条查问 SQL 能够有 N 种执行形式,优化器的最终目标是找到最好的执行打算,交给执行引擎去执行。

然而理论应用中咱们常常会发现,Mysql 常常有抉择错索引的状况,我明明有更快的索引,后果它不必,导致搞出了慢查问。

这是因为 Mysql 的优化器是基于老本模型的优化器,他只是基于已有的老本计算公式来抉择一个老本最低的执行形式,这个执行形式不肯定会是最快的,只能说大多数时候,优化器的抉择比咱们本人的抉择更精确。

总的来说,这个优化过程太简单了,流程大抵就是下图所示,更具体的内容能够看《数据库查问优化器的艺术原理解析与 SQL 性能》这本书(我切实是懒得看了,吐了)。

执行引擎

大部分外围的事件曾经被优化器解决完了,最初执行引擎只有依据生成好的执行打算查问数据返回就好了,这一步绝对就挺简略了。

执行引擎只须要依据执行打算的指令调用存储引擎的 API 就能够了。

当然这一步如果能够缓存查问后果,那么就在这个阶段把查问后果缓存下来,而后把后果返回给客户端就能够了。

总结

一图胜千言。

退出移动版