一、前言
一直是想知道一条SQL语句是怎么被执行的 , 它执行的顺序是怎样的 , 然后查看总结各方资料 , 就有了下面这一篇博文了 。
本文将从MySQL总体架构--->查询执行流程--->语句执行顺序来探讨一下其中的知识 。
二、MySQL架构总览
架构最好看图 , 再配上必要的说明文字 。
下图根据参考书籍中一图为原本 , 再在其上添加上了自己的理解 。
文章插图
从上图中我们可以看到 , 整个架构分为两层 , 上层是MySQLD的被称为的‘SQL Layer’ , 下层是各种各样对上提供接口的存储引擎 , 被称为‘Storage Engine Layer’ 。其它各个模块和组件 , 从名字上就可以简单了解到它们的作用 , 这里就不再累述了 。
三、查询执行流程
下面再向前走一些 , 容我根据自己的认识说一下查询执行的流程是怎样的:
1、连接
1.1、客户端发起一条Query请求 , 监听客户端的‘连接管理模块’接收请求;
1.2、将请求转发到‘连接进/线程模块’;
1.3、调用‘用户模块’来进行授权检查;
1.4通过检查后 , ‘连接进/线程模块’从‘线程连接池’中取出空闲的被缓存的连接线程和客户端请求对接 , 如果失败则创建一个新的连接请求;
2、处理
2.1、先查询缓存 , 检查Query语句是否完全匹配 , 接着再检查是否具有权限 , 都成功则直接取数据返回;
2.2、上一步有失败则转交给‘命令解析器’ , 经过词法分析 , 语法分析后生成解析树;
2.3、接下来是预处理阶段 , 处理解析器无法解决的语义 , 检查权限等 , 生成新的解析树;
2.4、再转交给对应的模块处理;
2.5、如果是SELECT查询还会经由‘查询优化器’做大量的优化 , 生成执行计划;
2.6、模块收到请求后 , 通过‘访问控制模块’检查所连接的用户是否有访问目标表和目标字段的权限;
2.7、有则调用‘表管理模块’ , 先是查看table cache中是否存在 , 有则直接对应的表和获取锁 , 否则重新打开表文件;
2.8、根据表的meta数据 , 获取表的存储引擎类型等信息 , 通过接口调用对应的存储引擎处理;
2.9、上述过程中产生数据变化的时候 , 若打开日志功能 , 则会记录到相应二进制日志文件中;
3、结果
3.1、Query请求完成后 , 将结果集返回给‘连接进/线程模块’;
3.2、返回的也可以是相应的状态标识 , 如成功或失败等;
3.3、‘连接进/线程模块’进行后续的清理工作 , 并继续等待请求或断开与客户端的连接;
4、一图小总结
文章插图
四、SQL解析顺序
接下来再走一步 , 让我们看看一条SQL语句的前世今生 。
首先看一下示例语句:
文章插图
然而它的执行顺序是这样的:
文章插图
虽然自己没想到是这样的 , 不过一看还是很自然和谐的 , 从哪里获取 , 不断的过滤条件 , 要选择一样或不一样的 , 排好序 , 那才知道要取前几条呢 。
既然如此了 , 那就让我们一步步来看看其中的细节吧 。
1、准备工作
1.1、创建测试数据库
文章插图
1.2、创建测试表
文章插图
1.3、插入数据
文章插图
1.4、最后想要的结果
文章插图
推荐阅读
- mysql库不能修改为utf8mb4编码,但又想存emoji表情怎么办?
- MySql Binlog事件介绍篇
- MySQL中的这17个关键问题,一定要弄清楚
- MySQL DBA必读:万字归总表设计与SQL编写技巧
- 详解Mysql数据库不同字符集下迁移方法
- Mysql数据库连接查询
- mysql 数据分析如何实现日报、周报、月报和年报?
- MySQL 触发器
- ThinkPHP 5.0添加mysql存session驱动
- Mysql 为什么要选择 B+Tree