MySQL-浅析查询SQL语句执行过程

过程概览

一.查询缓存

MySQL会用一张引用表,将查询缓存以Key-Value的方式进行缓存,Key是查询语句,Value则是查询语句的结果,并且通过一个哈希值来引用,此哈希值受查询语句整体、当前执行查询的数据库、甚至是客户端协议版本等影响。

在查询缓存阶段,首先会对执行语句的用户进行权限校验 ,有查询该表的权限的用户,才能继续进行。若上一次该查询语句缓存了结果,则可以直接返回结果给Client,直接省去解析、预处理、优化、执行的过程,能够提高数据库查询的性能。

但也正因为未进行解析、预处理,空格、注释(两条语句间任何 字符的不同)也会影响命中率,查询语句中包含了不确定的数据,也不会被缓存,如CURRENT_DATE()、自定义函数、临时表等,若表发生变化,查询缓存可能会失效,所以一般应用于多次使用、读取频繁且数据变化不频繁、数据量大的查询。

查询缓存默认是关闭的,若需要启用查询缓存,通过在服务器配置文件my.cnf 中添加query_cache_type=1或者query_cache_type=2,若等于2,则只对显示定义SQL_CACHE有效。

确定要执行的查询缓存,可以用SQL_CACHE显示指定:

csharp 复制代码
select SQL_CACHE column_name from table_name;

由于使用场景较少、可能导致并发性能问题,MySQL在8.0后版本移除了查询缓存。

二.解析器、预处理器

解析器是对查询语句通过词法分析(关键字)、语法解析(语法规则)来生成一个数据结构------解析树(select_lex),词法分析是将SQL语句拆成一个一个单词进行检查,而语法分析则顾名思义,检查语句是否符合SQL的语法规则,在此阶段,并不会对语句中的字段名、表名进行检查。

SQL语句若符合上述条件,则预处理器会进一步检查解析树是否合法,例如表、字段是否存在、命名、别名是否存在歧义,所以当语法错误和字段不匹配同时出现,会先报语法错误。

三.优化器

优化器会根据它认为的最优的执行计划执行,有多个索引,决定使用哪个索引,有多表关联,优先连接哪个表等。优化器会将传入的解析树生成一个/多个执行计划,执行计划的个数跟查询语句中的条件也有关系。生成执行计划会消耗较多时间,特别是当有多个执行计划的时候。

csharp 复制代码
select name from school where gender = 'Male'  and class = 9;

Plan A:先在school表中找出gender字段值为'Male'的行,再判断class字段值是否为9。

Plan B:先在school表中找出class字段值为9的行,再判断gender字段值是否为'Male'。

优化器分为两种:CBO基于代价的优化器、RBO基于规则的优化器,MySQL使用的是CBO

CBO会从多个执行路径中选择一个"成本"最小的执行路径来作为执行计划。成本的具体计算是非常复杂的,简单的说,成本代表了MySQL根据统计信息(如索引,表,行)通过成本模型计算出来目标SQL对应的步骤的IO,CPU等消耗,也就是说统计信息的大小、成本模型的合理性影响着执行计划的选择。

如果使用的是预编译SQL,则经过一次编译,就能够多次运行,省去解析、优化的过程。

如果此时存在执行计划缓存,就可以直接使用已缓存的执行计划,跳过生成执行计划,加快查询SQL的速度。

四.执行器

执行器根据传入的执行计划完成整个查询,但首先会检查用户是否拥有对该表的操作权限,再根据表的引擎定义调用引擎接口去根据执行计划对表进行查询。

如果不存在过滤,MySQL将进行全表扫描,返回所有行。

如果存在过滤,根据条件过滤(若存在索引,且开启了索引下推,则交由存储引擎完成),符合则存储在结果集中,不符合则跳过,如此遍历到最后。

当有一条结果生成,其实就在开始准备向Client返回数据了,一旦整个查询的结果集被完整获取并存储在缓存中,MySQL 会一次性将整个结果集返回给Client,所以看起来就像是一次性发送的。

五.存储引擎

MySQL5.6之后 新增了索引下推的功能:将执行器数据筛选的过程交由存储引擎 处理,减少了Server层(解析器预处理器、优化器、执行器)的负担,提高查询的效率,特别是在使用索引的时候,可以减少扫描的数据量,减少不必要的读取。

索引下推:在传统的查询流程中,MySQL通过索引检索符合条件的行,然后通过回表 操作获取实际的数据行。因为索引通常只存储了行的标识符(PRIMARY KEY/ID),而不是完整的行数据,所以才需要回表。而索引下推会将部分where子句中的条件下推到索引扫描过程中,在索引扫描的同时过滤,因为在索引扫描的时候还未读取整个行数据,且减少了回表的数量,所以特别是在大表和复杂查询中,能够显著提高查询的性能。

索引下推默认是开启的,也可以在系统变量中查看index_condition_pushdown的值是否为on。

sql 复制代码
show variables like 'optimizer_switch'\G;

参考文章链接:

sql执行流程概述_sql执行过程-CSDN博客

一条SQL语句在MySQL中执行过程全解析_本篇文章会分析下---个sql语句在mysql中的执行流程,包括sql的查询在mysql内部会怎-CSDN博客

MySQL进阶学习(一)----MySQL架构与SQL执行流程 - 掘金

MySQL探秘(二):SQL语句执行过程详解 - 掘金

MySQL教程2:从MySQL的逻辑架构看SQL查询语句是如何被执行的,了解连接管理、解析器、查询优化器、执行引擎,Server层和引擎层各自的作用 - 掘金

MySQL的SQL预处理(Prepared) - 海东潮 - 博客园

mysql之优化器、执行计划、简单优化 - 烟雨楼人 - 博客园

MySQL查询语句完整语法解析 - Hu.R - 博客园

相关推荐
momo小菜pa2 小时前
【MySQL 06】表的增删查改
数据库·mysql
程序员大金5 小时前
基于SpringBoot+Vue+MySQL的装修公司管理系统
vue.js·spring boot·mysql
gorgor在码农5 小时前
Mysql 索引底层数据结构和算法
数据结构·数据库·mysql
-seventy-5 小时前
SQL语句 (MySQL)
sql·mysql
一般路过糸.5 小时前
MySQL数据库——索引
数据库·mysql
无敌少年小旋风7 小时前
MySQL 内部优化特性:索引下推
数据库·mysql
翔云1234567 小时前
MVCC(多版本并发控制)
数据库·mysql
静听山水8 小时前
mysql语句执行过程
数据库·mysql
Q_w77429 小时前
一个真实可用的登录界面!
javascript·mysql·php·html5·网站登录
容器( ु⁎ᴗ_ᴗ⁎)ु.。oO10 小时前
MySQL事务
数据库·mysql