mysql执行过程
- 连接器:管理连接(tcp协议)。验证身份(username/password),通过验证后建立连接,根据是否长时间未操作数据库,超时断开连接。
- 缓存器:缓存结果。客户端发送查询语句,先从缓存器查看是否已经执行过该sql,如果执行过,直接返回结果。mysql8.0 因命中率不高,已去除。
- 分析器:分析sql语法是否正确。若错误,则报语法错误
- 优化器:
SQL
执行前会使用优化器进行优化,mysql会选择出最优的查询方案 - 执行器:执行sql。首先会校验sql是否有权限操作表,其次调用存储引擎api操作数据。
sql执行过程
事实上,mysql并不是按照我们写的sql顺序进行执行,它内部有自己的sql执行顺序。为了清楚的使用sql,我们需要打入内部,做到知己知彼,百战不殆
。执行过程中,会产生临时表
。
- from
- join
- on
- where
- group by : 开始使用select中的别名,后面也可使用
- avg,sum…
- having
- select
- distinct
- order by
- limit
执行过程:
第一步:执行from子句
,若有两张表,会进行笛卡尔积,生成一个虚拟表
。
第二步:根据join算法
,筛选数据,生成一个虚拟表
。
第三步:如果form子句中大于2张表
,则重复
进行第1、2步,生成新的虚拟表
第四步:执行where语句,对前面产生的最终虚拟表进行条件过滤,产生新的虚拟表
。
第五步:执行group by语句,对虚拟表进行分组,产生虚拟表
。如果使用group by,所得的虚拟表的列为group by后定义的列和聚合函数组成,其后只能使用该虚拟表中的列
。
第六步:执行having语句,产生新的虚拟表
。
第七步:执行select语句,筛选出需要的数据,产生新的虚拟表
。
第八步:执行distinct语句,去除相同的行,产生新的虚拟表
。如果使用了group by,此处是多余的操作。因为分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。
第九步:执行order by子句。sql基于集合理论,是逻辑集合
,成员的顺序是无关紧要的,不需要排序。那么如果进行排序,则会返回一个对象
(包含物理顺序的逻辑组织,游标
)。所以非必要不排序
。此处是唯一一个可以使用列别名的地方
。
第十步:应用top选项,将结果返回给客户端
。
示例
select name,class_name,max(grade)
from student t1
left join class t2
on t1.cid = t2.id
where name = '张三'
limit(0,2)
复制代码
- 从student表中获取数据,产生
虚拟表v1
- 虚拟表v1和class表,根据
join算法
,产生虚拟表v2
- 根据where条件,对v2进行过滤,产生
虚拟表v3
- 执行select,筛选列,产生
虚拟表v4
- 对v4执行limit,将
结果返回给客户端
。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END