做SQL优化的前提就必须要清楚当一个SQL被发送到Mysql时,它的处理流程。下面通过一个SQL优化分析过程来详细了解Mysql对SQL执行流程原理。
1、Mysql架构
在上篇文章中已经做了简单架构介绍,Mysql架构分为两个大的组件:Server层、存储层
Mysql服务层主要工作为连接器、查询缓存、解析器、优化器、执行计划、执行器等
存储引擎层: 存储引擎负责MySQL中数据的存储与提取,与底层系统文件进行交互。
可以看出来Mysql架构中Server层和存储引擎层是完全解耦独立运行的组件,所以MySQL存储引擎是插件式的,即可以选择不同的引擎使用,甚至可以自己写一个。
服务器中的查询执行引擎(执行器)通过接口与存储引擎进行通信。
简单的说,存储引擎本身是一个比较单纯的服务组件,它只负责与硬件交互,进行数据的读取和存储工作,而这一切的读写行为都是按照Server层提供执行计划来实施。
2、SQL执行流程分析
通过一个SQL优化来了解下详细流程:
select * from project where tenantsid=286478108025408 and name = '测试专案20219999' and sales_code ='psm02';
根据表结构和SQL可以得到相关分析资讯,借此来深入了解执行流程:
流程步骤:
1、Sever层通过连接器接收到SQL请求后,优先查看缓存是否由满足条件的数据,没有则继续..
2、通过解析器分析,生成语法树 .... 优化器(不关注,不说了)
3、Sever层最终会生成一个执行计划,执行器就根据执行计划来调用存储引擎进行交互。
执行计划:
可以看出来,执行计划中几乎已经将整个的执行过程交代的很清楚,后续就是单纯的按照执行计划来交互执行:
上面交互流程涉及到了索引查询、ICP、回表、数据过滤等过程,当然Mysql远不止这些流程。
3、SQL优化
现在清楚了当前SQL的执行流程,我们可以知道:
1、ICP原理:server层在生成执行计划时,会将不能通过索引查询,但是可以利用索引结果进行过滤出的条件下推到存储引擎进行数据过滤,这样可以进一步过滤掉数据,减少后续回表的操作。一般使用到了索引下推可以通过执行计划extra查看,如果有use_index_condition表示进行了索引下推。
2、回表原理:因为索引树中叶子节点数据不能满足需要的栏位,所以需要通过主键ID,到主键索引中查询,这是IO操作,所以要尽量的减少这样的回表操作。
3、数据过滤:通过执行索引无法直接过滤的条件,server层会对其进行再次过滤操作,一般在执行计划中extra中存在using where表示需要进一步数据过滤行为。
4、索引覆盖:因为索引查询结果不能涵盖需要的栏位,所以才需要回表操作回去到需要的栏位信息,如果二级索引已经包含了需要的栏位,这里就不需要回表查询。
分析了执行计划,也了解了原理,接下来优化就变得简单了,
调整索引为index02(tenantsid,name,sales_code,code)
select tenantsid,name from project where tenantsid=286478108025408 and name = '测试专案20219999' and sales_code ='psm02';
可以看出来查询成本从702降到了1.2