例如一个简单的SQL语句:
mysql> select * from T where ID=10;
在 MYSQL 内部是怎么执行的呢?我们从头梳理一下。
client 首先要与 MySQL 建立连接,这就需要一个连接器,负责与 client 建立连接、权限验证、管理连接。
client 和 server 连接完成了,向 server 发送 sql 请求,连接器不会直接处理,会转给分析器,对这条 sql 进行词法分析,例如识别出来“select”关键字,知道这是一个查询语句,识别出表明、字段名等,词法分析之后就是语法分析,判断是否满足 mysql 语法。
经过分析器之后,MySQL就知道要做什么了,然后是怎么做,由优化器完成。
例如:
mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
方案1:
先从表 t1 里面取出 c=10 的记录的 ID 值,再根据 ID 值关联到表 t2,再判断 t2 里面 d 的值是否等于 20。
方案2:
先从表 t2 里面取出 d=20 的记录的 ID 值,再根据 ID 值关联到 t1,再判断 t1 里面 c 的值是否等于 10。
这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。
在比如一个表中有多个索引,具体使用哪一个?也是由优化器来决定。
知道了做什么、怎么做,下面就是真正开始干了,由执行器负责具体执行。
执行器的基本执行逻辑:
调用存储引擎“取满足条件的第一行”这个接口,然后循环取“满足条件的下一行”这个接口,将所有满足条件的行组成结果集返还给客户端。
至此,这个语句就执行完了。
总体来说,MySQL 分为2个层次:server 层、存储引擎层。
server 层包括连接器、分析器、优化器、执行器,涵盖 MySQL 的核心服务,以及所有的内置函数(如日期、时间、数学、加密函数等),还有所有跨存储引擎的功能,例如存储过程、触发器、视图等。
其实 server 层中还有一个查询缓存,一个语句进来后先看是否在缓存中有,如果有就直接返回,如果没有再走分析器,但由于实际环境中查询缓存的作用很小,上面的描述中就没有提及,而且在 MySQL 8 中已经去掉了查询缓存。
存储引擎层负责数据的存储和提取,是插件式的架构。
内容整理自极客时间的专栏《MySQL 实战45讲》,讲的很好,推荐学习