当前位置:网站首页>mysql - sql执行过程
mysql - sql执行过程
2022-06-22 14:38:00 【炸了毛的猫】
一、组件介绍
1、连接器
1)负责与客户端的通信,是半双工模式,这就意味着某一固定时刻只能由客户端向服务器请求或者服务器向客户端发送数据,而不能同时进行。
2)验证用户名和密码是否正确(数据库mysql的user表中进行验证),如果错误返回错误通知(deAcess nied for user ‘root’@‘localhost’(using password:YES)),如果正确,则会去 mysql 的权限表(mysql中的 user、db、columns_priv、Host 表,分别存储的是全局级别、数据库级别、表级别、列级别、配合 db 的数据库级别)查询当前用户的权限。
2、缓存(Cache)
也称为查询缓存,存储的数据是以键值对的形式进行存储,如果开启了缓存,那么在一条查询sql语句进来时会先判断缓存中是否包含当前的sql语句键值对,如果存在直接将其对应的结果返回,如果不存在再执行后面一系列操作。如果没有开启则直接跳过。
3、分析器
对客户端传来的 sql 进行分析,这将包括预处理与解析过程,并进行关键词的提取、解析,并组成一个解析树。具体的解析词包括但不局限于 select/update/delete/or/in/where/group by/having/count/limit 等,如果分析到语法错误,会直接抛给客户端异常:ERROR:You have an error in your SQL syntax.
比如:select * from user where userId =1234;
在分析器中就通过语义规则器将select from where这些关键词提取和匹配出来,mysql会自动判断关键词和非关键词,将用户的匹配字段和自定义语句识别出来。这个阶段也会做一些校验:比如校验当前数据库是否存在user表,同时假如User表中不存在userId这个字段同样会报错:unknown column in field list.
4、优化器
进入优化器说明sql语句是符合标准语义规则并且可以执行。优化器会根据执行计划选择最优的选择,匹配合适的索引,选择最佳的方案。比如一个典型的例子是这样的:
表T,对A、B、C列建立联合索引(A,B,C),在进行查询的时候,当sql查询条件是:select xx where B=x and A=x and C=x.很多人会以为是用不到索引的,但其实会用到,虽然索引必须符合最左原则才能使用,但是本质上,优化器会自动将这条sql优化为:where A=x and B=x and C=X,这种优化会为了底层能够匹配到索引,同时在这个阶段是自动按照执行计划进行预处理,mysql会计算各个执行方法的最佳时间,最终确定一条执行的sql交给最后的执行器。
优化器会根据扫描行数、是否使用临时表、是否排序等来判断是否使用某个索引,其中扫描行数的计算可以通过统计信息来估算得出,而统计信息可以看作是索引唯一数的数量,可以使用部分采样来估算,具体就是选择 N 个数据页,统计这些页上数据的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了。但是因为索引数据会变化,所以索引的统计信息也会变化。当变更的数据行数超过 1/M 的时候,就会重新计算一次统计信息。
5、执行器
执行器会调用对应的存储引擎执行 sql。主流的是MyISAM 和 Innodb。
MyISAM 和 Innodb 的索引数据结构是B+树
memory索引数据结构是 hash表

二、执行过程
1、写操作

2、读操作
查询的过程和更新比较相似,但是有些不同,主要是来源于他们在查找筛选时的不同,更新因为在查找后会进行更新操作,所以查询这一行为至始至终都在缓冲池中(使用到索引且缓冲池中包含数据对应的数据页)。而查询则更复杂一些。
创建表:
create table tbl_test (a int primary key, b int, c int, d int, e varchar(50));
create index idx_bcd on tbl_test(b, c, d);
insert into tbl_test values (4,3,1,1,'a');
insert into tbl_test values (1,1,1,2,'d');
insert into tbl_test values (8,8,7,8,'h');
insert into tbl_test values (2,2,1,2,'g');
insert into tbl_test values (5,2,2,5,'e');
insert into tbl_test values (3,3,2,1,'c');
insert into tbl_test values (7,4,0,5,'b');
insert into tbl_test values (6,5,2,4,'f');
在执行 select * from tbl_test where b >= 2 and b < 7 and c > 0 and d != 2 and e != ‘a’; 在提取时,会将 Where 条件拆分为 Index Key(First Key & Last Key)、Index Filter 与 Table Filter。
1、Index Key
用于确定 SQL 查询在索引中的连续范围(起始点 + 终止点)的查询条件,被称之为Index Key;由于一个范围,至少包含一个起始条件与一个终止条件,因此 Index Key 也被拆分为 Index First Key 和 Index Last Key,分别用于定位索引查找的起始点以终止点。
Index First Key
用于确定索引查询范围的起始点;提取规则:从索引的第一个键值开始,检查其在 where 条件中是否存在,若存在并且条件是=、>=,则将对应的条件加入Index First Key之中,继续读取索引的下一个键值,使用同样的提取规则;若存在并且条件是 >,则将对应的条件加入 Index First Key 中,同时终止 Index First Key 的提取;若不存在,同样终止 Index First Key 的提取。
针对 SQL:select * from tbl_test where b >= 2 and b < 7 and c > 0 and d != 2 and e != ‘a’,应用这个提取规则,提取出来的 Index First Key 为 b >= 2, c > 0 ,由于 c 的条件为 >,提取结束
Index Last Key
用于确定索引查询范围的终止点,与 Index First Key 正好相反;提取规则:从索引的第一个键值开始,检查其在 where 条件中是否存在,若存在并且条件是 =、<=,则将对应条件加入到 Index Last Key 中,继续提取索引的下一个键值,使用同样的提取规则;若存在并且条件是 < ,则将条件加入到 Index Last Key 中,同时终止提取;若不存在,同样终止Index Last Key的提取
针对 SQL:select * from tbl_test where b >= 2 and b < 7 and c > 0 and d != 2 and e != ‘a’,应用这个提取规则,提取出来的 Index Last Key为 b < 7 ,由于是 < 符号,提取结束
2、Index Filter
在完成 Index Key 的提取之后,我们根据 where 条件固定了索引的查询范围,那么是不是在范围内的每一个索引项都满足 WHERE 条件了 ? 很明显 4,0,5 , 2,1,2 均属于范围中,但是又均不满足SQL 的查询条件
所以 Index Filter 用于索引范围确定后,确定 SQL 中还有哪些条件可以使用索引来过滤;提取规则:从索引列的第一列开始,检查其在 where 条件中是否存在,若存在并且 where 条件仅为 =,则跳过第一列继续检查索引下一列,下一索引列采取与索引第一列同样的提取规则;若 where 条件为 >=、>、<、<= 其中的几种,则跳过索引第一列,将其余 where 条件中索引相关列全部加入到 Index Filter 之中;若索引第一列的 where 条件包含 =、>=、>、<、<= 之外的条件,则将此条件以及其余 where 条件中索引相关列全部加入到 Index Filter 之中;若第一列不包含查询条件,则将所有索引相关条件均加入到 Index Filter之中
针对 SQL:select * from tbl_test where b >= 2 and b < 7 and c > 0 and d != 2 and e != ‘a’,应用这个提取规则,提取出来的 Index Filter 为 c > 0 and d != 2 ,因为索引第一列只包含 >=、< 两个条件,因此第一列跳过,将余下的 c、d 两列加入到 Index Filter 中,提取结束
3、Table Filter
这个就比较简单了,where 中不能被索引过滤的条件都归为此中;提取规则:所有不属于索引列的查询条件,均归为 Table Filter 之中
针对 SQL:select * from tbl_test where b >= 2 and b < 7 and c > 0 and d != 2 and e != ‘a’,应用这个提取规则,那么 Table Filter 就为 e != ‘a’
在5.6 之前,是不分 Table Filter 与 Index Filter 的,这两个条件都直接分配到 Server 层进行筛选。筛选过程是先根据 Index Key 的条件先在引擎层进行初步筛选,然后得到对应的主键值进行回表查询得到初筛的行记录,传入 Server 层进行后续的筛选,在 Server 层的筛选因为没有用到索引所以会进行全表扫描。而索引下推的优化就是将 Index Filter 的条件下推到引擎层,在使用 Index First Key 与 Index Last Key 进行筛选时,就带上 Index Filter 的条件再次筛选,以此来过滤掉不符合条件的记录对应的主键值,减少回表的次数,同时发给 Server 层的记录也会更少,全表扫描筛选的效率也会变高。
下面是未使用索引下推和使用索引下推的示意图:

下面是使用索引下推和使用索引下推的示意图:

3、总结

这里要注意的是如果在一开始没有用到索引,会依次将磁盘上的数据页读取到缓冲池中进行查询。
原文地址:https://www.cnblogs.com/mengxinJ/p/14045520.html#_label2
边栏推荐
- 米哈游六月社招火热开启!500+岗位,超多HC,就在这个夏天(附内推方式)
- [Newman] postman generates beautiful test reports
- 宏源期货开户安全么?宏源期货公司可以降低手续费?
- vector的模拟实现
- Yilian technology rushes to Shenzhen Stock Exchange: annual revenue of RMB 1.4 billion, 65% of which comes from Ningde times
- mysql的concat()函数如何用
- 小程序开发----自定义有效期缓存
- 类似attention nlp
- C语言学习-18-makefile文件编写例子以及如何生成、调用动态库
- UK considers listing arm in London based on national security
猜你喜欢

Recommend several AI Intelligent Platforms

HMS core news industry solution: let technology add humanistic temperature

Binary search (integer binary)

架构师之路,从「存储选型」起步

Self inspection is recommended! The transaction caused by MySQL driver bug is not rolled back. Maybe you are facing this risk!

Navicat Premium 连接Oracle 数据库(图文教程)

C语言学习-18-makefile文件编写例子以及如何生成、调用动态库

mysql如何修改存储引擎为innodb

How MySQL modifies a field to not null

Charles 乱码问题解决
随机推荐
数字人民币可以买理财产品了!建行APP在试点地区上线服务专区,实测体验如何?
TDengine 连接器上线 Google Data Studio 应用商店
米哈游六月社招火热开启!500+岗位,超多HC,就在这个夏天(附内推方式)
ROS2前置基础教程 | 小鱼教你用CMake依赖查找流程
Is pioneer futures reliable? How to open a futures account safely?
Fast and accurate point cloud registration based on minimizing 3D NDT distance
Advanced thinking on application scenarios of standardization, maximum normalization and mean normalization
Tdengine connector goes online Google Data Studio store
Maze problem (BFS record path)
【VTK】模型旋转平移
Charles 乱码问题解决
FPGA collects DHT11 temperature and humidity
华为云HCDEZ专场暨分布式技术峰会:华为云分布式云原生技术与实践之路
C语言学习-17-函数作为参数传入函数
Exploration and practice of dewu app data simulation platform
【newman】postman生成漂亮的测试报告
Common operations in Visual Studio development
宏源期货开户安全么?宏源期货公司可以降低手续费?
C语言学生成绩排名系统
又可以这样搞nlp(分类)