一条SQL执行的完整流程解析 - 《从0到1-全面深刻理解MySQL系列-第四篇》

本文主要是介绍一条SQL执行的完整流程解析 - 《从0到1-全面深刻理解MySQL系列-第四篇》,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


  • 个人主页: IT学习日记
  • 版权: 本文由【IT学习日记】原创、在CSDN首发
  • 如果文章对你有帮助欢迎关注、点赞、收藏(一键三连)有任何问题欢迎私信,看到会及时回复!

文章大纲

  • 一、前言
  • 二、孽缘,一条SQL是如何被执行
    • 2.1、连接处理模块:
    • 2.2、解析和优化模块
      • 2.2.1、查询缓存
      • 2.2.2、语法解析
      • 2.2.3、查询优化
    • 3、存储引擎模块
    • 4、延伸
  • 三、MySQL流程常见面试题
      • 3.1、数据库语句的执行顺序
  • 四、系列文章
  • 五、小结

一: 前言

一、前言

  • 大家好,我是小诚,《从0到1-全面深刻理解MySQL系列》已经来到第四章,这一章节的主要从一条SQL执行的开始,由浅入深的解析SQL语句由客户端到服务器的完整执行流程,最终达到 “知其然、知其所以然” 的目的。

  • 最近时常会收到一些小伙伴反馈的问题,为了方便交流,所以创建了交流群,感兴趣的可以添加,欢迎大家一起交流,吹水,摸鱼,进步。

  • 《从0到1-全面深刻理解MySQL系列》系列文章会持续更新,感兴趣的小伙伴可以关注我,一起加油,一起进步!,如有帮助,不要忘记一键三联哦,ღ( ´・ᴗ・` )比心!

二: 孽缘,一条SQL是如何被执行

二、孽缘,一条SQL是如何被执行


  前几天在网上进行了一个面试,关于数据库方面的面试题其实也没少背,但是这个面试官的问题多少让我有些触不及防,他没有询问比较常见的基础语法和优化的问题,而是让我解释一条SQL从客户端到服务端的执行流程,这让我十分尴尬,因为平时只顾应用层面的东西,没有真正去理解到更深层次的东西,所以遇到非常规问题,很容易蒙圈,希望大家以我为鉴,学习一个知识要尽量达到"知其然、知其所以然",这样即使面试官变换问题的角度,我们也能更好的应对回答,叨唠完了,正片开始!


  平常工作中,我们最常见的就是从客户端发送一条SQL到数据库服务端进行相应的数据表操作,其实抽象起来就是: 客户端(也就是我们的业务代码)发送了一段SQL文本,服务端接收到了一段SQL文本然后进行解析处理,最终返回一段文本(执行结果)。


  那实际上服务端是对客户端进行了哪些解析步骤的操作才最终返回执行结果的呢?这里我们首先通过一张图片形象的展示解析的流程,然后再对逐个流程进行具体的解析。


在这里插入图片描述

2.1、连接处理模块:

  该模块主要是管理客户端的连接,客户端可以通过TCP/IP、命名管道、共享内存、套接字等方式与服务端进行连接,服务端接收到连接后,会专门生成一个线程去处理客户端的请求,当完成客户端的请求后,该线程不会被销毁,而是放入线程池中,从而减少了频繁创建和删除线程的消耗,大大节省了系统资源和提高了效率。

  客户端每次发起连接请求时,都会携带用户名、密码等验证信息,如果服务器验证不通过,则会拒绝连接,同时,如果很多客户端同时请求连接,为了避免服务端程序崩溃和提高效率,可以限制最大的连接数量。

2.2、解析和优化模块


  客户端和服务端建立完连接后,服务端会有专门的线程对客户端的请求做处理,此时服务端接收到的是客户端发送的一段文本信息,需要转换成自己可以识别的信息,具体步骤如下:

2.2.1、查询缓存


  试想,周末晚上你用手机看电影学习经验,突然老板给来了个电话,让你去处理一个紧急事情,你不得不中断看电影去处理突发事件,处理完后你肯定是想从上一次播放的位置继续观看而不是从头观看,缓存的作用就体现在这里。


  为了提高响应效率,Mysql服务端程序会根据客户端请求的信息生成对应的缓存,如果请求的信息符合缓存中的,则直接返回,无需再去与底层进行更多的交互


  但是、Mysql服务器程序并不能像人一样智能,如果两次的请求文本不一样如多了空格、大小写以及每次调用会返回不同的值的函数等情况时,都不会命中缓存,因为它无法判断多出来的这些东西是否会影响SQL最终执行的结果。


  使用到了缓存,就涉及到对缓存维护,Mysql中的缓存检测程序会监测到缓存涉及的每一张表,如果表中的数据或者结构发生改变,如执行了insert、alter等命令时,那么它会将该表对应的缓存进行失效和删除。因为维护缓存是需要很大的开销,特别是表很多的情况下,所以Mysql8.0时已经将查询缓存这个流程删除。

2.2.2、语法解析


    如果请求没有命中缓存,则进入到语法解析的步骤,因为服务端程序接收到的是客户端发送过来的文本信息,Mysql服务端程序要从文本中将具体的请求含义解析出来,如查询什么字段,查询哪一些表等

2.2.3、查询优化


    经过语法解析步骤后,服务端程序已经知道客户端请求的信息,如请求的表,数据等,但是,此时服务器程序还不会立马根据这些信息去执行.它会解析出来的语句进行一些优化,如:子连接转为关联查询,内外连接查询等,以达到最大的优化效率,优化的结果就是生成一个执行计划,就是平常我们使用Explain关键字看到的一个结果。

3、存储引擎模块


  经过了连接处理和解析优化俩步骤后,实际上还是没有对实际的数据进行任何的处理,Mysql中,将对数据存储和提取的操作抽取到了一个叫存储引擎的模块中


  在逻辑上,我们看到的是表的数据是一行行的形式,但实际物理层面上,表的数据如何存储、如何读取表的数据、这都是存储引擎需要负责的操作,Mysql中提供了不同的存储引擎,不同的存储引擎存储的数据结构可能不相同,采用的算法也可能不同

4、延伸


  我们常在一些教学视频或者专业文章中看到MySQL Server层和存储引擎模块的概念,它们具体的含义如下:


  为了管理方便,将连接处理/管理、查询缓存、语法解析、查询优化等不涉及到真实数据存取的功能划分为Mysql Server层的功能。


  把涉及到真实数据存取的功能划分为存储引擎模块的功能,Mysql Server层通过各个存储引擎提供的API进行访问响应的存储引擎,Mysql通过查询优化生成了执行计划后,通过调用存储引擎提供的API获取到对应的数据返回给客户端即可。


三、MySQL流程常见面试题


3.1、数据库语句的执行顺序


  (一): 执行顺序


  from -> on -> join -> where -> group by -> having -> count(聚合函数) -> select -> distinct -> order by -> limit


  (二): 执行步骤解释:


  (1)、from: 表示数据的来源


  (2)、on: 表示数据的关联表,执行完后生成一个临时表t1,提供给下一步的操作使用


  (3)、join: 将join表的数据补充到on执行完成的临时表t1中,如: left join则将坐标剩余的数据添加到临时表t1中,如果join超过3个,则重复on…join之间的步骤。


  (4)、where: 根据携带的条件,从临时表中筛选出符合条件的数据,并生成临时表t2。


  (5)、groub by: 根据携带的条件,将临时表t2进行相应的数据分组,并形成临时表t3,如果语句包含了group by则它后面的字段必须出现在select中或者出现在聚合函数中,否则会报SQL语法错误。


  (6)、having: 筛选分组后临时表t3的数据,得到临时表t4。


  (7)、count等聚合函数: 对临时表进行指定字段的聚合函数操作,形成临时表t5。


  (8)、select: 从临时表筛选出需要返回的数据,形成临时表t6。


  (9)、distinct: 对临时表t6进行指定的去重筛选,形成临时表t7。


  (10)、order by: 对临时表t7排序,形成临时表t8。


  (11)、limit: 筛选返回的数据条数


  想要了解更多的执行过程的问题,可以查看之前专门解析执行过程的文章: 你真的懂使用Group by?


四、系列文章

  1、《从0到1-全面深刻理解MySQL系列》- 最详细的MySQL安装流程(Window版)


  2、《从0到1-全面深刻理解MySQL系列》- 最详细的MySQL安装流程(Linux环境)


  3、《从0到1-全面深刻理解MySQL系列》- 忘记MySQL登录密码时如何连接数据库

五、小结


  从上文我们可以知道,MySQL服务端又划分为: MySQL Server层和存储引擎层。MySQL Server层主要负责进行客户端连接、语法解析、语法优化等操作,存储引擎层负责对实际数据的存取操作。


  一条SQL语句完整的解析需要经历以下步骤: 客户端和服务端请求处理 -》查询缓存 -》语法解析 -》查询优化 -》存储引擎对数据存取 -》 返回处理结果

   下次遇到面试官询问这种问题,直接甩这篇文章在他脸上。最后、如果觉得文章对你有帮助,不要忘记一键三连哦,你的支持是我创作更加优质文章的动力,有任何问题可以私信我,看到会及时给你答复!

这篇关于一条SQL执行的完整流程解析 - 《从0到1-全面深刻理解MySQL系列-第四篇》的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/671134

相关文章

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

全面解析Golang 中的 Gorilla CORS 中间件正确用法

《全面解析Golang中的GorillaCORS中间件正确用法》Golang中使用gorilla/mux路由器配合rs/cors中间件库可以优雅地解决这个问题,然而,很多人刚开始使用时会遇到配... 目录如何让 golang 中的 Gorilla CORS 中间件正确工作一、基础依赖二、错误用法(很多人一开

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Python极速搭建局域网文件共享服务器完整指南

《Python极速搭建局域网文件共享服务器完整指南》在办公室或家庭局域网中快速共享文件时,许多人会选择第三方工具或云存储服务,但这些方案往往存在隐私泄露风险或需要复杂配置,下面我们就来看看如何使用Py... 目录一、android基础版:HTTP文件共享的魔法命令1. 一行代码启动HTTP服务器2. 关键参

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优