Select * from user的千层套路

Select * from user的千层套路

​ 作为一个java程序员,我们会经常和sql打交道,但是有事情我们确实不知道sql语句背后的处理逻辑比如下面这个sql

select * from user where id='1';

​ 对于这么一条操作来说mysql服务器做了哪些处理呢?下面我们将说一下关于mysql数据库中对sql语句的处理逻辑

MySql的基本架构

​ 要想要了解sql语句的内部处理逻辑,我们需要先学习Mysql的基本架构图,这样才能更好的把握Mysql数据库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-62fx4rBp-1592558179311)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200619140642.png)]

​ 从图中我们可以清楚的看到Mysql的架构和各个模块以及SQL语言的执行过程。

​ Mysql数据库整体可以分为Server层和存储引擎层两部分。其中Server层是共有的,而存储引擎层是可以以插件的形式进行扩展

​ 一条Sql语句大概会经历链接管理、解析与优化、最后到存储引擎,这三个模块

连接管理

​ 连接管理是SQL语句执行过程中的第一关,控制着客户端和Server服务端的交互,连接管理主要工作是客户端的身份认证和连接线程的管理、

​ 每个客户端与Server建立连接时,服务器会创建一个线程来与客户端交互,交互的第一项内容就是验证客户端的身份,认证凭证是基于客户端发起连接请求时携带的主机信息、用户名、密码。

​ 如果认证失败,则结束连接任务,并且返回Access denied for user的错误

​ 如果认证成功,还会到权限表中查询该用户的权限,在此次连接下,后续的权限判断都是基于此时读取的权限为依据。

  • 主要是负责客户端与服务端进行连接,当然在连接线程上,连接管理也做了优化,并不是每个客户端执行完任务之后,就把该线程销毁,连接管理会把这些线程缓存起来,等待新的连接,这也就不会频繁的创建和销毁线程,从而节约了开销。

解析与优化

​ 完成连接管理之后,SQL 语句执行的第二步就是解析和优化,SQL 语句查询的所有操作都在这里了。

查询缓存

​ MySQL 服务器拿到查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中。key 是查询的语句,value 是查询的结果。

​ 但是实际使用中会有很多问题:

  • 命中率低下:只要有稍微的不同就不会命中
  • 缓存数据发送了变化,导致取到错误数据
  • 一旦表中数据或结构改变了缓存也会删除

​ 所以缓存对 MySQL 数据库来说弊大于利,所以在 MySQL 8.0 版本直接将查询缓存的整块功能删掉了

语法解析和预处理

​ 如果查询缓存没有命中,接下来就需要进入正式的查询阶段了。因为客户端程序发送过来的请求只是一段文本而已,所以 MySQL 服务器程序首先要对这段文本做语法解析。

​ 首先通过关键字将 SQL 语句进行解析,并且生成一个“解析树”。MySQL 解析器将使用 MySQL 语法规则验证和解析查询,例如,关键字是否使用正确、关键字的顺序是否正确或者引号是否前后匹配等。

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

查询优化

​ MySQL 的优化程序会对我们的语句做一些优化,如外连接转换为内连接、表达式简化、子查询转为连接等等。优化的结果就是生成一个执行计划,这个执行计划表明了应该使用哪些索引进行查询,表之间的连接顺序是啥样的。

执行器

​ 执行器会执行查询优化后的执行计划,通过与存储引擎交互,完成数据的查询操作,返回最终的数据结果。

​ 开始执行的时候,要先判断一下你对这个表 T 有没有执行查询的权限,如果没有,就会返回没有权限的错误

​ 如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。

比如我们这个例子中的表 user 中,假设 ID 字段没有索引,那么执行器的执行流程是这样的:

1、调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中;

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

3、执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

到这里,执行 SQL 语句就执行完了,其实这内部还是非常复杂的。

存储引擎

​ 到上面为止,SQL 语句就执行完了,但是与真实数据打交道的是存储引擎,存储引擎是 MySQL服务器对数据的存储和提取操作的封装模块。我们知道表是由一行一行的记录组成的,但这只是一个逻辑上的概念,物理上如何表示记录,怎么从表中读取数据,怎么把数据写入具体的物理存储器上,这都是存储引擎负责的事情。

​ 为了实现不同的功能,MySQL提供了各式各样的存储引擎,不同存储引擎管理的表具体的存储结构可能不同,采用的存取算法也可能不同。比如,MySQL5.7 之后默认的 InnoDB 存储引擎。

SQL提供了各式各样的存储引擎,不同存储引擎管理的表具体的存储结构可能不同,采用的存取算法也可能不同。比如,MySQL5.7 之后默认的 InnoDB 存储引擎。

猜你喜欢

转载自blog.csdn.net/issunmingzhi/article/details/106860408
今日推荐