目录
1、MySQL中SQL语句的执行
i. 整体的 MySQL 流程 :
a、 连接层:客户端和服务器端建立连接,客户端发送 SQL至服务器端
b、SQL层:对 SQL 语句进行查询处理
c、存储引擎层:与数据库文件打交道,负责数据的存储和读取
ii. SQL 语句在 MySQL 中的流程
a、流程: SQL 语句→缓存查询→解析器→优化器→执行器。
b、查询缓存:查询缓存中有 SQL 语句,就会直接将结果返回给客户端;如果没有,就进入到解析器阶段。需要说明的是,因为查询缓存往往效率不高,所以在 MySQL8.0 之后就抛弃了这个功能。 c、解析器:在解析器中对 SQL 语句进行语法分析、语义分析。 d、优化器:在优化器中会确定 SQL 语句的执行路径,比如是根据全表检索,还是根据索引来检索等。 e、 执行器:在执行之前需要判断该用户是否具备权限,如果具备权限就执行 SQL 查询并返回结果。在 MySQL8.0 以下的版本,如果设置了查询缓存,这时会将查询结果进行缓存。
2、基础架构:SQL查询语句执行流程
1.MySQL的逻辑架构图
a、MySQL 可以分为 Server 层和存储引擎层两部分。
b、Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等
c、存储引擎层负责数据的存储和提取, 架构模式是插件式,事务支持是在引擎层实现的,支持 InnoDB(常见、默认的)、MyISAM(与InnoDB对比、不足)、Memory 等多个存储引擎。
2.连接器
连接器负责跟客户端建立连接、获取权限、维持和管理连接
3.查询缓存
查询命中缓存,MySQL 不需要执行后面的复杂操作;语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中 命中查询缓存,会在查询缓存返回结果的时候,做权限验证
3.分析器
a、“词法分析” :识别出里面的字符串分别是什么,代表什么。
b、语法分析” :根据语法规则,判断你输入的 SQL 语句是否满足 MySQL 语法 、
4.优化器
优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。
5.执行器
a、MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。
b、开始执行的时候,要先判断一下你对这个表 T 有没有执行查询的权限
c、有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口
d、ID 字段没有索引,那么执行器的执行流程:
i.调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中;
ii.调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
iii.执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。
iv.语句执行完成
e、ID 字段有索引,那么执行器的执行流程:
i.调用的是“取满足条件的第一行”这个接口
ii.之后循环取“满足条件的下一行”这个接口 (这些接口都是引擎中已经定义好的)
3、查询优化器是如何工作的
1.什么是查询优化器
事务和索引的使用是数据库中的两个重要核心,事务可以让数据库在增删查改的过程中,保证数据的正确性和安全性,而索引可以帮数据库提升数据的查找效率。
a、SQL语句执行流程:
b、分析器:
i.语法分析:检查 SQL 拼写和语法
ii.语义检查:检查 SQL 中的访问对象是否存在
c、查询优化器:
i.目标:找到执行 SQL 查询的最佳执行计划(查询树:一系列物理操作符按照一定的运算关系组成的查询执行计划)
ii.逻辑查询优化(代数语法级优化) :基于关系代数进行的查询重写,对 SQL 语句进行等价变换(对条件表达式进行等价谓词重写、条件简化,对视图进行重写,对子查询进行优化,对连接语义进行了外连接消除、嵌套连接消除等 )
iii.物理查询优化(物理层面) :关系代数的每一步都对应着物理计算,物理计算往往存在多种算法,需要计算各种物理路径的代价,选择代价最小的作为执行计划 (对于单表和多表连接的操作,需要高效地使用索引,提升查询效 )
2.两种优化方式
a、基于规则的优化器(RBO,Rule-Based Optimizer) :通过在优化器里面嵌入规则,来判断 SQL 查询符合哪种规则,就按照相应的规则来制定执行计划,同时采用启发式规则去掉明显不好的存取路径 (规则:以往的经验或已被证明的有效的方式 )
b、基于代价的优化器(CBO,Cost-Based Optimizer) :根据代价评估模型,计算每条可能的执行计划的代价,也就是 COST,从中选择代价最小的作为执行计划。
c、CBO 对数据更敏感,会利用数据表中的统计信息来做判断,针对不同的数据表,查询得到的执行计划可能不同,制定的执行计划也更符合数据表的实际情况。
d、SQL 是面向集合的语言,并没有指定执行的方式,在优化器中会存在各种组合的可能。需要通过优化器来制定数据表的扫描方式、连接方式以及连接顺序,从而得到最佳的 SQL 执行计划。
3.CBO是如何统计代价的
a、能调整的代价模型的参数 :
server 层(mysql.server_cost:主要是CPU代价) :
i.disk_temptable_create_cost:表示磁盘临时表文件(MyISAM 或 InnoDB)的创建代价,默认值为 20
ii.disk_temptable_row_cost:表示临时表文件(MyISAM 或 InnoDB)的行代价,默认值 0.5
iii.key_compare_cost:表示键比较的代价。键比较的次数越多,这项的代价就越大,这是一个重要的指标,默认值 0.05
iv.memory_temptable_create_cost:表示内存中临时表的创建代价,默认值 1
v.memory_temptable_row_cost:表示内存中临时表的行代价,默认值 0.1。
vi.row_evaluate_cost:统计符合条件的行代价,如果符合条件的行数越多,那么这一项的代价就越大,默认值 0.1
存储引擎层 (mysql.engine_cost :主要统计页加载代价,主要是I/O代价) :
i.io_block_read_cost:从磁盘中读取一页数据的代价,默认是 1。
ii.memory_block_read_cost:从内存中读取一页数据的代价,默认是 0.25。
b、代价模型如何计算
i.总代价 = I/O代价+CPU代价
ii.I/O代价:即PAGE FETCH,页面加载的代价(数据页和索引页)
iii.CPU代价:即W*(RSI CALLS) (W :权重因子,CPU 到 I/O 之间转化的相关系数;CALLS 代表了 CPU 的代价估算(键比较(compare key)以及行估算(row evaluating) )))
iv.总代价 = I/O 代价 + CPU 代价 + 内存代价 + 远程代价
4、日志系统:SQL更新语句执行流程
1.SQL更新语句执行流程
a、MySQL 可以恢复到半个月内任意一秒的状态
b、更新语句的执行流程和查询语句的一致
c、在一个表上有更新的时候,跟这个表有关的查询缓存会失效,这条语句就会把表 T 上所有缓存结果都清空
d、分析器会通过词法和语法解析知道这是一条更新语句。优化器决定要使用 ID 这个索引。然后,执行器负责具体执行,找到这一行,然后更