SQL执行原理

sql

一个 SQL 的执行过程为:

  1. 连接数据库

  2. 查询缓存

  3. 词法分析

  4. 语法分析

  5. 语义分析

  6. 构造执行树

  7. .生成执行计划

  8. 执行器执行计划

  9. 返回执行结果

连接器

首先客户端连接mysql时就是连接到了连接器上,连接器负责跟客户端建立连接/校验用户身份,获取权限。连接命令一般如下:

mysql -h ip地址 -P 端口 -u 用户 -p

当客户端输入完了用户名和密码开始连接时,连接器会校验:

  • 如果用户名或者密码不正确,客户端会收到一个“Access denied for user”的错误。
  • 如果用户名和密码校验正确,连接器会检查用户所拥有的权限。之后,这个连接里的权限逻辑判断,都依赖此时读到的权限。

这就意味着一个用户成功建立连接之后,即使你用管理员把这个用户的权限更改了,也是不会影响到已经连接的这个用户,除非这个用户断开重新连接。让连接器重新读取权限才可以。

查询缓存

连接建立成功之后,你就能够执行select等语句了,这时就会进行第二步:查询缓存

Mysql收到一个sql请求之后,先检查缓存,看看之前是不是有执行过。如果执行过并缓存没有过期,结果会以key-value的形式存储在内存中,key是查询语句,value是查询结果。如果有缓存,直接把对应的value返回给客户端。

如果语句不在查询缓存中,就会向下执行下面的阶段,执行完成后,会把结果放到缓存中。

查询缓存的失效很平凡,因为只要更新一个表,那么这个表的所有查询缓存结果都会被清空,所以对经常变更的表,查询缓存的命中率很低。除非这个表数据比较稳定,不经常改变,才适合查询缓存。

分析器

如果没用命中缓存,分析器就开始工作了,对sql语句进行解析。

首先分析器会做“词法分析”,你输入的多个字符加上空格组成的sql语句,分析器需要分析出来里面字符分别都代表什么。

如从你输入的”select”关键字开始,mysql知道这是一个查询语句,然后分析出那个是表名,那个是你输入的条件等等。

做完了词法分析,开始做“语法分析”,根据词法分析的结果,语法分析会判断你输入的这条sql语句是否符合Mysql语法。

如果你的语句不对,就会收到“You have an error in you SQL syntax”的错误提醒

优化器

经过了分析器,Mysql已经知道你要做什么了,在开始执行之前,还需要经过优化器的处理。

优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联的时候,决定各个表的连接顺序。

执行器

Mysql通过分析器知道了你要做什么,通过优化器知道了如何做,接下来就是执行器开始执行语句;

开始执行之前, 会先判断你对要操作的表或库有没有权限,如果没有就返回权限的错误。

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

比如这个select语句:select * from db1 where ID=100;

  • 先调用Inodb引擎接口获取表的第一行,判断ID值是不是100,如果不是则跳过,如果是则将结果存在结果集中;
  • 调用引擎接口获取“下一行”,重复相同的判断逻辑,直到读取这个表的最后一行。
  • 执行器将上述遍历过程所有符合要求的结果返回给客户端。

至此,这个select语句算是执行完了。

数据库的慢查询日志中会看到rows_examined的字段,表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。

有些情况下,执行器调用一次,在引擎内部则扫描了多行,因此引擎扫描行数跟rows_examined并不完全相同。

有用就打赏一下作者吧!