Mysql SQL执行流程

1. Mysql 中的sql执行流程

MySQL 的查询流程:

1. 查询缓存: Server 如果在查询缓存中发现了这条sql语句,就会直接将结果返回给客户端;如果没有,就进入到解析端。需要说明的是,因为查询缓存往往效率不高,所以在mysql8.0中废弃此功能。

大多数情况下查询缓存是个鸡肋,为什么?

查询缓存是提前把查询的结果缓存起来,这样下次不需要执行就可以直接拿到结果。需要说明的是,在mysql中的查询缓存,不是缓存查询计划,而是擦汗寻对应的结果。这就意味着查询匹配的鲁棒性大大降低,只有相同的查询操作才会命中查询缓存。两个查询请求在任何字符上的不同,都会导致缓存不会命中。因此mysql的查询缓存命中不高。

同时,如果查询请求中包含某些系统函数,用户自定义变量和函数,一些系统表,如mysql,information_schema, performance_schema 数据库中的表,那这个请求就不会被缓存。以某些系统函数举例,可能同样的函数的两次调用会产生不一样的结果,比如函数now,每次调用都会产生最新的当前事件,如果在一个查询中调用了这个函数,那即使查询请求的文本信息都一样,那不同的时间的两次查询也应该得到不同的记过,如果在第一次查询时就缓存了,那第二次查询的时候直接用第一次就是错误的。

此外,既然是缓存,那就有他的缓存失效, mysql缓存系统会检测设计到的每张表,只要该表的结构或者数据被修改,那使用该表的所有钙塑缓存查询都将变为无效并从缓存中删除!对于更新压力大的数据库来说,查询缓存的命中率会非常低。

总之,因为查询缓存往往利大于弊,查询缓存失效非常频繁。

2. 解析器:在解析器中对sql语句进行语法分析,语义分析。

分析器先做 ‘ 词法分析 ’。你输入的是由多个字符串和空格组成的一条sql语句,mysql 需要识别处里里面的字符串分别是什么,代表什么。

mysql从你输入的 select 这个关键字识别出来,这是一个查询语句。他也要把字符串 T 识别成表名 T,他字符串 ID 识别成列 ID。

接着,要做 ‘ 语法分析 ’。 根据词法分析的结果,语法分析器(比如:Bison)会根据语法规则,判断是输入的这个sql语句是否满足 mysql 语法。

如果你的语法不对,就会收到 ‘ You have an error in your sql syntax’ 的错误提醒

 3. 优化器: 在优化器中会确定sql语句执行的路径,比如是根据全表检索,还是根据索引检索等。

经过了解析器,mysql就知道你要作什么了。在开始执行之前,还要先经过优化器的处理。一条查询可以有很多执行方式,最后都返回相同结果。优化器的作用就是找到这其中最好的执行计划。

比如:优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联join的时候,决定各表的连接顺序,还有表达式简化,子查询转为连接,外连接转为内连接等。

举例:

select * from test1 join test2 using(ID)
where test1.name='zhangwei' and test2.name='mysql高级课程'; 

方案1:可以先从表test1里面取name='zhangwei' 的记录id,再根据id值关联到test2,在判断test2里面name='mysql高级课程'

方案1:可以先从表test2里面取name='mysql高级课程' 的记录id,再根据id值关联到test1,在判断test2里面name='zhangwei'

这两种执行方法的逻辑姐u共是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择使用哪一个方案。优化器阶段完成后,这个语句的执行方案就确定下来了,然后进入执行器阶段。

在查询优化器中,可以分为 逻辑 查询优化 阶段和 物理查询 优化阶段。

 3. 执行器:

在执行之前需要判断该用户是否具备权限。如果没有,就会返回权限错误,如果具备权限,就执行sql查询并返回结果。

如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,调用存储引擎api对表进行读写。存储引擎api只是个抽象接口,下面还有个存储引擎层,具体实现还是要看表选择的存储引擎。

sql语法顺序

select distinct  # 手写顺序
    <select_list>
from 
    < left_table > < join_type >
join < right_Table > on < join_condition >
where 
    < where_condition >
group by
    < group_by_list >
having
    < having_condition >
order by
    < order_by_condition >
limit < limit_number >


from < left_table >  # 机器读取顺序
on < join_condition >
< join_type > join < right_Table >
where < where_condition >
group by < group_by_list >
having < having_condition >
select 
distinct <select_list>
order by < order_by_condition >
limit < limit_number >

查看sql语句执行的历史记录

show profiles;

show profile; # 查看最近一条执行的sql详情 ( show profile for query 7; 查看指定的语句)

每个环节所花费的时间如下:

starting    开始状态

checking permissions  检查权限

opening tables   打开表

init  初始化

System lock  锁系统

optimizing  优化器

statistics  统计

preparing  准备

executing  执行

end  结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值