MySQL—一条查询SQL语句的完整执行流程

MySQL—一条查询SQL语句的完整执行流程

表结构和数据如下:

表结构和数据

我们分析的sql语句如下:

select tb_id,tb_name,tb_address from tb_user where tb_id = 66;

大体来说,MySQL可以分为Server层和存储引擎层两部分:

Server层

  • 包括:连接器、查询缓存、分析器、优化器、执行器等

  • 涵盖MySQL的大多数核心服务功能

  • 所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现

    • 比如:存储过程、触发器、视图等
  • 存储引擎层:

    • 负责数据的存储和提取
    • 可插拔式存储引擎:InnoDB、MyISAM、Memory等
      • 最常用存储引擎是InhoDB
      • 从MySQL 5.5版本开始,默认存储引擎是lnnoDB

SQL执行流程

第一步:连接到数据库

首先会连接到这个数据库上,这时候接待我们的就是连接器。

mysql -uroot -p

连接数据库

连接完成后,如果没有后续的动作,这个连接就处于空闲状态。客户端如果太长时间没动静,连接器就会自动将它断开。这个时间是由参数wait_timeout控制的,默认值是8小时。

show processlist;

其中的 Command 列显示为“Sleep”的这一行,就表示现在系统里面有一个空闲连接。

连接状态

第二步:查缓存

MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以key-value对的形式,被直接缓存在内存中。key是查询的语句hash之后的值,value是查询的结果。

  • 如果查询语句在缓存中,会被直接返回给客户端。

  • 如果语句不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。

如果查询命中缓存,MySQL不需要执行后面的复杂操作就可以直接返回结果,效率会很高!但是不建议使用MySQL的内置缓存功能。

查询缓存

查询缓存默认是关闭的状态。

# 查看是否开启缓存
show variables like 'query_cache_type';
# 查看缓存的命中次数:
show status like 'qcache_hits';

查询缓存相关内容

开启缓存

/etc/my.cnf文件中修改“query_cache_type”参数

值为`0或OFF`会禁止使用缓存。
值为`1或ON`将启用缓存,但以`SELECT SQL_NO_CACHE`开头的语句除外。
值为`2或DEMAND`时,只缓存以`SELECT SQL_CACHE`开头的语句。

清空查询缓存

可以使用下面三个SQL来清理查询缓存:

# 清理查询缓存内存碎片。
FLUSH QUERY CACHE; 
# 从查询缓存中移出所有查询。
RESET QUERY CACHE;
# 关闭所有打开的表,同时该操作将会清空查询缓存中的内容。
FLUSH TABLES; 

清空查询缓存

不建议使用MySQL的查询缓存

因为查询缓存往往弊大于利

  • 成本高:查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。因此很可能你费劲地把结果存起来,还没使用呢,就被一个更新全清空了。

  • 命中率不高:对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务就是有一张静态表,很长时间才会更新一次。比如,一个系统配置表,那这张表上的查询才适合使用查询缓存。

  • 功能并不如专业的缓存工具更好:redis、memcache、ehcache…
    MySQL提供了按需使用的方式,我们可以将参数query_cache_type设置成DEMAND,这样对于默认的SQL语句都不使用查询缓存。而对于你确定要使用查询缓存的语句,可以用SQL_CACHE显式指定,像下面这个语句一样:

    select sql_cache * from tb_user where tb_id = 16;
    

MySQL 8.0 版本直接将查询缓存的整块功能删掉了。

第三步:分析SQL语句

如果查询缓存没有命中,接下来就需要进入正式的查询阶段了。客户端程序发送过来的请求,实际上只是一个字符串而已,所以MySQL服务器程序首先需要对这个字符串做分析,判断请求的语法是否正确,然后从字符串中将要查询的表、列和各种查询条件都提取出来,本质上是对一个SQL语句编译的过程,涉及词法解析、语法分析、预处理器等。

  • 词法分析:词法分析就是把一个完整的SQL语句分割成一个个的字符串;
  • 语法分析:语法分析器根据词法分析的结果做语法检查,判断你输入的SQL语句是否满足MySQL语法;
  • 预处理器:预处理器则会进一步去检查解析树是否合法,比如表名是否存在,语句中表的列是否存在等等,在这一步MySQL会检验用户是否有表的操作权限。

词法分析

比如我们前文所提到的sql语句,分割前为:

select tb_id,tb_name,tb_address from tb_user where tb_id = 66;

分割后为

select,
tb_id,
tb_name,
tb_address,
from,
tb_user,
where,
tb_id,
=,
66
;

MySQL同时需要识别出这个SQL语句的字符串分别是什么,代表什么。

  • 把select关键字识别出来,是查询语句;
  • 把tb_user识别出来是表名tb_user

语法分析

如果语法正确就会根据MySQL语法规则与SQL语句生成一个数据结构——解析树

如果我们把from写成form

会报出如下错误:

报出错误

我们前面的SQL语句,生成解析树如下:

select tb_id,tb_name,tb_address from tb_user where tb_id = 66;

解析树

预处理器

预处理器会进一步去检查解析树是否合法,比如表名是否存在,语句中表的列是否存在等等,在这一步MySQL会检验用户是否有表的操作权限。

预处理之后会得到一个新的解析树,然后调用对应执行模块。

第四步:优化SQL语句

优化器顾名思义就是对查询进行优化。作用是根据解析树生成不同的执行计划,然后选择最优的执行计划。

MySQL里面使用的是基于成本模型的优化器,哪种执行计划Explain执行时成本最小就用哪种。而且它是io_cost和cpu_cost的开销总和,它通常也是我们评价一个查询的执行效率的一个常用指标。

show status like 'Last_query_cost';

查看上次查询成本开销

查看上次查询成本开销,默认值是0

优化器可以做的优化有:

  • 当有多个索引可用的时候,决定使用哪个索引;
  • 在一个语句有多表关联(join)的时候,决定各个表的连接顺序,以哪个表为基准表。

优化器最多是辅助,作用很有限,我们的SQL语句不能依赖于MySQL的优化器去调优!

第五步:执行SQL语句

判断执行权限

开始执行的时候,要先判断一下对这表tb_user有没有执行查询的权限,如果没有权限,就会返回无权限的错误。

比如:我们新建一个用户hello_user,只有库sjdwz_testtab_test的查询权限,没有表tb_user的查询权限。

CREATE USER `hello_user`@`localhost` IDENTIFIED BY '7654321@Hello';
GRANT Select ON TABLE `sjdwz_test`.`tab_test` TO `hello_user`@`localhost`;

截图

使用这个用户hello_user连接mysql,

mysql -uhello_user -p

执行下面的查询语句,就会返回没有权限的错误

select tb_id,tb_name,tb_address from tb_user where tb_id = 66;

报出无权限

调用存储引擎接口查询

如果有权限,就使用指定的存储引擎打开表开始查询。执行器会根据表的引擎定义,去使用这个引擎提供的查询接口提取数据。

  • tb_id是主键执行流程:
    • 调用InnoDB引擎接口,从主键索引中检索c_id=14的记录。
    • 主键索引等值查询只会查询出一条记录,直接将该记录返回客户端。
    • 至此,这个语句就执行完成了。
  • tb_id不是主键执行流程:全表扫描
    • 调用InnoDB引擎接口取这个表的第一行,判断tb_id 值是不是66,如果不是则跳过,如果是则将这行缓存在结果集中;
    • 调用引擎接口取”下一行",重复相同的判断逻辑,直到取到这个表的最后一行。
    • 执行器将上述遍历过程中所有满足条件的行组成的结果集返回给客户端。
    • 至此,这个语句就执行完成了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/566022.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV-基于阴影勾勒的图纸清晰度增强算法

作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 实现原理 大家在工作和学习中,无论是写报告还是论文,经常有截图的需求,比如图表、图纸等&…

【PCL】教程global_hypothesis_verification 通过验证模型假设来实现 3D 对象识别与位姿估计...

测试程序1 milk.pcd milk_cartoon_all_small_clorox.pcd 终端输出1: Model total points: 12575; Selected Keypoints: 193 Scene total points: 307200; Selected Keypoints: 7739 [pcl::SHOTEstimation::computeFeature] The local reference frame is not valid!…

若依集成mybatisplus报错找不到xml

引用:https://blog.csdn.net/qq_65080131/article/details/136677276 MybatisPlusAutoConfiguration中可以知道,系统会自动配置SqlSessionFactory,,但是,当你有自定义的SqlSessionFactory,,就会…

Spark-机器学习(4)回归学习之逻辑回归

在之前的文章中,我们来学习我们回归中的线性回归,了解了它的算法,知道了它的用法,并带来了简单案例。想了解的朋友可以查看这篇文章。同时,希望我的文章能帮助到你,如果觉得我的文章写的不错,请…

NCH WavePad for Mac:功能全面的音频编辑利器

NCH WavePad for Mac是一款功能全面的音频编辑软件,专为Mac用户设计。它集音频录制、编辑、处理和效果添加于一体,为用户提供一站式的音频解决方案。 NCH WavePad for Mac v19.16注册版下载 作为一款专业的音频编辑器,WavePad支持对音频文件进…

软件测试之【合理的利用GPT来辅助软件测试一】

读者大大们好呀!!!☀️☀️☀️ 🔥 欢迎来到我的博客 👀期待大大的关注哦❗️❗️❗️ 🚀欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言GPT的原理及技巧GPT辅助接口自动化测试 前言 在编程基础栏目中&#xff…

OSI七层模型、TCP/IP五层模型理解(个人解读,如何理解网络模型)

OSI七层模型 七层模型,亦称OSI(Open System Interconnection)。参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系,一般称为OSI参考模型或七层模型。它是一个七层的、抽象的模…

漫谈HAMR硬盘的可靠性-2

很显然,HAMR已经成为业内用于提升HDD硬盘容量硬盘的技术手段。三家机械硬盘HDD厂商,希捷、西数、东芝都已对HAMR硬盘进行了十多年的研究,但只有希捷大胆押注HAMR。相反,东芝和西部数据在采用HAMR之前选择了能量辅助垂直磁记录&…

Qt 跨平台开发

Qt 跨平台开发 文章目录 Qt 跨平台开发摘要第一 \ & /第二 神奇{不能换行显示第三 预处理宏 关键字: Qt、 win、 linux、 lib、 MSVC 摘要 最近一直在琢磨Qt跨平台开发的问题,缘由有以下几个, 首先第一个,我们目前开发…

如何查看redisson-spring-boot-starter和SpringBoot 对应版本

如何查看redisson-spring-boot-starter和SpringBoot 对应版本 我目前没有找到官网的地址来来查看对应关系。 所以我只能找pom.xml来查看 先在mvnrepository 找到redisson-spring-boot-starter的列表 具体地址是:https://mvnrepository.com/artifact/org.redisso…

查看项目go代码cpu利用率

1.代码添加: "net/http"_ "net/http/pprof"第二步,在代码开始运行的地方加上go func() {log.Println(http.ListenAndServe(":6060", nil))}() 2.服务器上防火墙把6060打开 3.电脑安装:Download | Graphviz …

Quarto Dashboards 教程 2:Dashboard Layout

「写在前面」 学习一个软件最好的方法就是啃它的官方文档。本着自己学习、分享他人的态度,分享官方文档的中文教程。软件可能随时更新,建议配合官方文档一起阅读。推荐先按顺序阅读往期内容: 1.quarto 教程 1:Hello, Quarto 2.qu…

【无监督+自然语言】GPT,GPT-2,GPT-3 方法概述 (Generative Pre-Traning)

主要参考 【GPT,GPT-2,GPT-3 论文精读【李沐论文精读】-2022.03.04】 https://www.bilibili.com/video/BV1AF411b7xQ/ 大语言模型综述: http://t.csdnimg.cn/4obR4 发展节点 2017.06 Transformer: 所有大语言模型LLMs的基础结构 , Attent…

Ubuntu下使用VisualStudioCode进行Java开发

0-1开始Java语言编程之路 一、Ubuntu下Java语言环境搭建 二、Ubuntu下Docker环境安装 三、使用Docker搭建本地Nexus Maven私有仓库 四、Ubuntu下使用VisualStudioCode进行Java开发 Visual Studio Code 下载 点击这个链接Visual Studio Code,进入VisualStudioCode的…

IDEA2023版本创建Sping项目无法使用Java8

1. 问题复现 1.1 当前版本2023.3.2 1.2 创建项目时:不存在jdk8选项 提示报错 1.3 原因分析 Spring官方发布Spring Boot 3.0.0 的时候告知了一些情况,Java 17将成为未来的主流版本 2. 如何解决 2.1 替换创建项目的源 我们只知道IDEA页面创建Spring项目…

CMake 编译项目

一、概述 cmake 是C一个很重要的编译和项目管理工具,我们在git 上以及常见的项目现在多数都是用cmake 管理的,那么我们今天就做一个同时有Opencv和CGAL 以及PCL 的项目。 二、项目管理 重点是CMakeList.txt 1、CMakeList.txt cmake_minimum_requir…

springcloudgateway集成knife4j

上篇我们聊聊springboot是怎么继承knife4j的。springboot3 集成knife4j-CSDN博客 本次我们一起学习springcloudgateway集成knife4j。 环境介绍 java:17 SpringBoot:3.2.0 SpringCloud:2023.0.0 knife4j : 4.4.0 引入maven配置…

javaEE初阶——多线程(八)——常见的锁策略 以及 CAS机制

T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 小比特 大梦想 此篇文章与大家分享分治算法关于多线程进阶的章节——关于常见的锁策略以及CAS机制 如果有不足的或者错误的请您指出! 多线程进阶 1.常见的锁策略 我们需要了解的是,我们使用是锁,在加锁 / 解锁…

树莓派学习笔记--Raspberry Pi OS系统烧录、SSH远程连接、VNC远程连接、设置静态IP地址

前言: 由于一些比赛的需求,目前我将开启一段时间的树莓派学习。目前还是处于一个啥也不知道的萌新状态。希望通过短期的学习能掌握树莓派的基本使用。 树莓派其实就是一个微型电脑,下面这个图是b站大佬整理的树莓派的各种型号配置&#xff0c…

LabVIEW轴承表面缺陷检测系统

LabVIEW轴承表面缺陷检测系统 为了解决轴承生产中人工检测效率低下、误检率高的问题,实现了一套基于LabVIEW的轴承表面缺陷自动检测系统。该系统利用工业相机采集轴承图像,通过图像处理技术对轴承表面的划痕缺陷和倒角缺陷进行自动识别和分析&#xff0…