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,如果不是则跳过,如果是则将这行缓存在结果集中;
    • 调用引擎接口取”下一行",重复相同的判断逻辑,直到取到这个表的最后一行。
    • 执行器将上述遍历过程中所有满足条件的行组成的结果集返回给客户端。
    • 至此,这个语句就执行完成了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Java实现动态心形图案

一、引言 在计算机图形学中,动态图案的生成和显示一直是一个令人兴奋的话题。心形图案作为情感表达的一种常见方式,在编程领域也颇受欢迎。本文将介绍如何使用Java编程语言实现动态心形图案,并附上相应的代码片段。 二、心形曲线的数学表达…

如何使用 ArcGIS Pro 快速为黑白地图配色

对于某些拍摄时间比较久远的地图,限于当时的技术水平只有黑白的地图,针对这种情况,我们可以通过现在的地图为该地图进行配色,这里为大家讲解一下操作方法,希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微…

使用大卫的k8s监控面板(k8s+prometheus+grafana)

问题 书接上回,对EKS(AWS云k8s)启用AMP(AWS云Prometheus)监控AMG(AWS云 grafana),上次我们只是配通了EKSAMPAMG的监控路径。这次使用一位大卫老师的grafana的面板,具体地址如下: ht…

汽车IVI中控开发入门及进阶(十五):AUTOSAR

前言: 随着汽车四化的进行,汽车电子系统standard标准化和coperation互操作性变得重要, AUTOSAR(AUTomotive Open System Architecture 汽车开放系统架构)框架已成为汽车行业的基础支柱。 AUTOSAR始自2000年,当时认识到标准化是有必要

Redis入门到通关之Redis数据结构-Set篇

文章目录 ☃️概述☃️数据结构☃️源码☃️其他 🌈 欢迎莅临我的个人主页👈这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地!🎇 🎓 博主简介: 我是请回答1024,一名Java领域深耕多年…

解读币安Megadrop:如何参加第一期BounceBit活动?

币安推出新的代币发行平台 Megadrop,第一期为 BounceBit。 跟 launchpool 相比, 主要不同是 1)锁仓 bnb 有收益的倍数加成 2)做任务有收益加成。 我认为核心目的有两个: 1)更多收益给 BNB 长期持有者&am…

jenkins修改全局安全配置之后登录错误

教训(流泪) 事情是这样的,第一次我需要用单点登录集成jenkins,jenkins可以通过插件的方式支持cas协议,我当时也不很懂,经过我学网上的一顿乱配置,jenkis上不去了,虽然这是公司本地环…

大数据——Zookeeper ZBA协议(四)

Zookeeper ZAB协议 概述 ZAB(Zookeeper Automic Broadcast)是一套专门为Zookeeper设计的用于进行原子广播和崩溃恢复的协议ZAB协议主要包含了两个功能 原子广播:保证数据一致性崩溃恢复:保证集群的高可用 ZAB协议本身是基于2PC算法来进行的设计&#…

记一次 Vscode + Latex 正向/反向搜索忽然失效

遥望大半个月前,完成论文撰写后,这些天虽然多次打开项目,但我真的一个字都没动过,今天想着开始着手修改一下,打开项目发现正向/反向搜索忽然失效了,感觉浑身有蚂蚁在爬,思索再三后找到问题&…

【数学归纳法 反证法】菲蜀定理

裴蜀定理(或贝祖定理,Bzout’s identity)得名于法国数学家艾蒂安裴蜀,说明了对任何整数a、b和它们的最大公约 数d,关于未知数x和y的线性不定方程(称为裴蜀等式):若a,b是整数,且&…

[测试]ChaosBlade: 丢包、延迟、断网、磁盘、cpu占用、内存占用等资源耗尽故障注入利器--编辑中

目录 ChaosBlade是什么? ChaosBlade可以制造哪些工况/故障? 使用文档 git仓库:chaosblade/README_CN.md at master chaosblade-io/chaosblade GitHub ChaosBlade是什么? ChaosBlade: 一个简单易用且功能强大的混沌实验实施工具 ChaosBlade是阿里巴巴开源的一款遵循混…

[图解]软件开发中的糊涂用语-04-为什么要追究糊涂用语

0 00:00:00,030 --> 00:00:05,620 今天呢,我们来说一个为什么要追究糊涂用语的问题 1 00:00:06,310 --> 00:00:06,548 2 00:00:06,548 --> 00:00:11,077 大家知道我们前些天都发了好几个视频 3 00:00:11,077 --> 00:00:13,461 追究这个糊涂用语 4 00…

如何搭建一个vue2组件库(king-ui-pro)

文章引用图片无法查看,直接查看原文 感兴趣的可以关注或订阅下这个系列,后续会陆续将相关的组件与公共方法进行分享 目前已经完成了的组件有 多行省略pro版,不是简单的多行省略效果 公共方法: 1、图片预览,知乎的图…

sql知识总结三

3.floor报错注入 (1)涉及到的函数 as 别名,group by 分组 >select concat_ws(-,(select database()),floor(rand()*2)) as a from users group by a; count()函数 汇总统计数量 >select count(*),concat_ws(-,(select database(0…

Attention和Transformer灵魂七问

1. 引言 最近,ChatGPT和其他聊天机器人将大语言模型LLMs推到了风口浪尖。这就导致了很多不是学ML和NLP领域的人关注并学习attention和Transformer模型。在本文中,我们将针对Transformer模型结构提出几个问题,并深入探讨其背后的技术理论。这…

YoloV9改进策略:下采样改进|自研下采样模块(独家改进)|疯狂涨点|附结构图

文章目录 摘要自研下采样模块及其变种第一种改进方法 YoloV9官方测试结果改进方法测试结果总结 摘要 本文介绍我自研的下采样模块。本次改进的下采样模块是一种通用的改进方法,你可以用分类任务的主干网络中,也可以用在分割和超分的任务中。已经有粉丝用…

【电控笔记5.4】pwm延迟

PWM延迟 1标准采样法 Td=MCU计算延迟+输出延迟 Tcon=电流控制周期 Ts=PWM载波周期 Td=1.5Ts(6.3节 ) 电流环跟PWM采样周期同步 2修改采样法

AR HUD_VSLAM+显示技术

智能座舱的一个重要技术方向是表达与展示。HUD可以将驾驶相关的信息,如车速、导航等投射到驾驶员的视线上方,避免驾驶员的目光离开前方道路。这种显示方式可以提供关键信息的实时展示,减少驾驶员的分心。 HUD的技术原理就是通过光学系统将信息…

【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!…

初入单元测试

单元测试:针对最小的功能单元(方法),编写测试代码对其进行正确性测试 Junit可以用来对方法进行测试,虽然是有第三方公司开发,但是很多开发工具已经集成了,如IDEA。 Junit 优点:可以灵活的编写测试代码&am…