【MySQL原理解析】01. 一条SQL查询语句是如何执行的

这是【MySQL原理解析】的第一篇文章,MySQL我看了很多的书与教程,对其原理有一定的理解,一直想写一系列的文章来把MySQL的原理给讲清楚,一直没有时间写,今天算是个开头吧。万事开头难,咱们先破了这个开头!

MySQL基本架构

我们常说,看一件事不要直接陷入细节,应该先从整体框架与流程上把握住,先从最高的维度理解问题,然后再逐步深入各个模块。学习MySQL也是一样,在使用MySQL的过程中,我们最开始都是从一条简单的查询语句开始。如在学生表student中按照学生的id来查学生的信息:

  select * from student where id = 100;

在我们程序员眼里,这就是一条sql语句,执行之后,返回一条结果。这看起来很简单的过程,实际在MySQL内部,却是一个非常复杂的过程。今天我们就来把这个过程拆解出来。
下面给出的是MySQL的基本架构示意图,从中可以看出SQL语句在MySQL的各个功能模块的执行过程。

在这里插入图片描述

MySQL的基本架构可以分为两大块,一块是Server层,一块是存储引擎层。

Server层包括连接器、查询缓存、分析器、优化器、执行器等。涵盖了MySQL大多数的核心服务功能、以及所有的内置函数,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器。视图等。

存储引擎层负责数据的存储与提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memmory等多个存储引擎。最常用的是InnoDB存储引擎。所以我们的系列文章也主要是以InnoDB存储引擎为主。

连接器

在客户端执行上面的查询语句时,客户端首先会与服务端建立一个TCP连接,每个客户端连接都会在服务端进程中拥有一个线程。这个连接的查询只会在这个单独的线程中执行,该线程只能轮流在某个CPU中运行。服务器会负责缓存线程,因此不需要为每一个新建的连接创建或者销毁线程。在连接的过程中还涉及到一些安全校验与权限校验等。

连接成功后,如果没有后续的动作,这个连接就处于空闲的状态,你可以使用 show processlist 命令来查看线程的各个状态。客户端如果长时间没有动静,连接器会自动将它断开。这个时间由参数wait_timeout控制,一般是8小时。如果在连接被断开后,客户端再次发送请求的话,就会收到一个错误提醒:Lost connection to MySQL server during query。这时候如果还要继续查询,就要重新建立连接,然后再执行请求。

在数据库领域,长连接是连接成功后,如果客户端有请求,则一直使用同一个连接。短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。

我们知道TCP建立连接的过程都是非常复杂的,所以应该降低建立连接这个动作,也就是尽量使用长连接。但是全部使用长连接后,有可能也会导致MySQL占用内存特别快,这是因为MySQL在执行的过程中,临时使用的内存都是管理在连接对象里的。这些临时使用的内存在断开连接才会被释放。所以如果长连接积累下来,可能导致占用内存太大,被系统强行杀掉(OOM),异常重启。

想要使用长连接,并且还要解决这种OOM问题的话,可以考虑以下两种方案。

  1. 定期断开长连接。使用一段时间,或者程序里面判断执行一个占用很大内存的查询后,断开连接,之后要查询再重连。
  2. 在比较新的MySQL版本中,可以在每次执行一个比较大的操作后,执行mysql_reset_connection操作来重新初始化连接资源。这个过程不需要重连和重新做权限校验等,但是会将连接恢复到刚刚创建完时的状态。

查询缓存

连接建立成功后,就可以进行select查询语句了。MySQL拿到一个查询请求后,会先到查询缓存看看之前是否有过一样的查询,如果有则直接返回结果。如果没有,才会进行后面的操作。

我们可以看到,查询缓存如果命中,就不会走后面的分析器、优化器以及存储引擎提取数据了。但是存储引擎在最新的MySQL8.0版本中已经不再支持查询缓存的功能了。为什么呢?

因为查询缓存失效非常频繁,只要有对一个表的更新操作,这个表上所的查询缓存都会被清空。因此很可能你费劲的把缓存建立起来,还没使用呢,就被一个更新全清空了。对于更新压力大的数据库来说,查询缓存的命中率会非常低。

分析器

解析器说白了就是对你输入的sql语句的解析,解析成MySQL这个服务端程序能够识别的代码。解析的过程中肯定会有判断sql语句是否正确的语法解析的过程。如果你的语法不对,肯定会报错。这个过程的原理涉及到词法分析树与语法分析树,较为复杂,这里暂时不深究。

优化器

经过分析器解析出MySQL能够识别出的代码后,优化器会对这部分查询代码做一系列的算法优化,包括重写查询、决定表的读取顺序,以及选择合适的索引等。用户可以通过特殊的关键字提示(hint)优化器,影响它的决策过程。也可以请求优化器解释(explain)优化过程的各个因素,使用户可以知道服务器是如何进行优化决策的。

对于优化器有哪些优化方法来优化查询,在后面的章节我们会详细说明。

执行器

MySQL通过分析器知道了你要做什么,通过优化器知道了该如何做,接下来就该真正的开始执行了。

在开始执行的时候,MySQL会再次判断本次查询是否对要查询的表有执行查询的权限,如果没有会报错。如果有权限就打开表继续执行。打开表的时候,执行器会根据这个表所使用的存储引擎,选择对应的存储引擎接口。

小结

本篇文章主要讲解了MySQL的基本架构,MySQL的整体架构还是非常复杂的,我们能够将MySQL的基本架构搞懂就行。这次主要学会一条查询语句,大致需要经历哪些流程,经过了哪些模块,每一个模块的细化流程都相当复杂,我们也不必把每一个模块都搞懂。作为一名后端开发人员,将优化器与存储引擎层的相关原理搞懂就可以。

在后面的章节,我们会深入学习优化器与存储引擎相关原理!

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

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

相关文章

【转载】MOS开关(verilog)

MOS开关 一. MOS开关 1. NMOS 源极(d)接Gnd 一般情况下,可认为晶体管受栅极(g)电平VG的控制(control). 1). VGH,源极(s)与漏极(d)接通; 2). VGL,源极(s)与漏极(d)断开. 源极(s)与漏极(d)接通, 则漏极(d)被下拉到Gnd. 2. PMOS 源极(d)接VDD 1)…

【Linux进程、线程、任务调度】二 fork/vfork与写时拷贝 线程的本质 托孤 进程睡眠和等待队列

学习交流加(可免费帮忙下载CSDN资源):个人微信: liu1126137994学习交流资源分享qq群1(已满): 962535112学习交流资源分享qq群2(已满): 780902027学习交流资源…

用Log4Net来记录系统的日志信息

[http://www.cnblogs.com/xhwy/archive/2011/11/25/2263495.html] 几乎所有的大型应用都会有自己的用于跟踪调试的API。因为一旦程序被部署以后,就不太可能再利用专门的调试工具了。然而一个管理员可能需要有一套强大的日志系统来诊断和修复配置上的问题。 经验表明…

扩展插件_Adobe扩展工具插件系列

Adobe系列软件相信大家都已了解到其功能的强大,除了软件之外Adobe系列的插件的功能也是不可忽略的。今天给大家分享的几款Adobe系列超强PS扩展工具,都是一些摄影师、设计师经常用的到的,可以提升不少工作效率,大家千万别错过哦&am…

【Linux进程、线程、任务调度】三 CPU/IO消耗型进程 吞吐率/响应 SCHED_FIFO算法与SCHED_RR算法 SCHED_NORMAL算法和CFS算法 nice与renic chrt

学习交流加(可免费帮忙下载CSDN资源):个人微信: liu1126137994学习交流资源分享qq群1(已满): 962535112学习交流资源分享qq群2(已满): 780902027学习交流资源…

dexpress 流程图_DevExpress控件使用经验总结

DevExpress是一个比较有名的界面控件套件,提供了一系列的界面控件套件的DotNet界面控件。本文主要介绍我在使用DevExpress控件过程中,遇到或者发现的一些问题解决方案,或者也可以所示一些小的经验总结。总体来讲,使用DevExpress控…

UCenter 表结构

Ucenter 数据库表结构说明uc_admins 管理员表数据表说明:管理员相关信息属性说明:uid mediumint(8) -- 用户IDusername char(15) -- 用户名allowadminsetting tinyint(1) --allowadminapp tinyint(1) --allowadminuser tinyint(1) --allowadminbadword t…

Java学习之路整理-技术书从入门到进阶最全50+本(珍藏版 )

学习交流加 个人微信:LyyCoder学习交流资源分享qq群1(已满): 962535112学习交流资源分享qq群2: 780902027一.速读一遍(最好在1~2天内完成) 人的大脑记忆力有限,在一天内快速看完一本…

问题 seata_架构设计 | 基于Seata中间件,微服务模式下事务管理

一、Seata简介1、Seata组件Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA、XA事务模式,为用户打造一站式的分布式解决方案。2、支持模式AT 模式基于支持本地 ACID 事务的关系型数…

Override and Overload (重写和重载)

1)方法的重写overriding和重载overloading是java多态性的不同表现. (2)重写overriding是父类与子类之间的多态性的一种表现,重载是一个类中多态性的表现。如果子类中定义方法与其父类有相同的名称和参数,我们说该方法被…

程序员史诗级必读书单吐血整理四个维度系列80+本书(珍藏版)

互联网行业的特点是变化。若要提高互联网开发的技能,就必须跟上技术发展的步伐。埋首醉心于项目开发与实战,固然能够锤炼自己的开发技巧,却难免受限于经验与学识。 世界上并不存在速成的终南捷径,但阅读好的技术书籍,尤…

示波器1m和50欧姆示阻抗匹配_示波器输入阻抗选1MΩ还是50Ω的详细解析

熟悉示波器的朋友可能都会有过这样的困惑:输入阻抗有1MΩ和50Ω两种,我们到底该如何选择呢?一、传输线想要讲清楚50Ω的由来,我们需要先讲一下传输线。电信号实际上是以电磁波的形式在传输线中传播的。当传输线的尺寸不再远小于电…

前端学习(355):小练习

.已知两个矩形,宽高分别是200200,400400,甲矩形的坐标是x1,y1.乙矩形的坐标是x2,y2. 写出判断条件两个矩形是否相碰撞 <script>x1200;//自己随意定义坐标x2200;y1400;y2400;var boolfalse;//先定义一个布尔值为falseif(x1>x2 && x1<x2400 && y1&g…

Quartus 中快速分配器件管脚

在quartus中分配器件管脚最笨的方法是对于器件手册一个一个的敲进去&#xff0c;这样做如果用到的管脚很好还没有发觉什么不好&#xff0c;但是当用到的器件管脚很多的时候就会发现很麻烦&#xff0c;而且容易出错。接下来我来介绍一种很方便的方法。 首先在txt文档中建立管脚和…

Web前端书单从HTML到JS到AJAX到HTTP从框架到全栈

前言&#xff1a;技术书阅读方法论 一.速读一遍&#xff08;最好在1~2天内完成&#xff09; 人的大脑记忆力有限&#xff0c;在一天内快速看完一本书会在大脑里留下深刻印象&#xff0c;对于之后复习以及总结都会有特别好的作用。 对于每一章的知识&#xff0c;先阅读标题&…

自定义背景_新版快绘精选:自定义背景墙 | 吊顶 | 云渲染滤镜升级

New自定义背景墙没有合适的背景墙样板&#xff1f;你需要一个全世界独一无二&#xff0c;独属于你monent的背景墙&#xff1f;没问题&#xff01;无论是要这样↓还是这样↓快绘都能帮到你&#xff01;-- 请观看视频 --New自定义吊顶除了可以自定义背景墙&#xff0c;新版快绘也…

【C++学习详细教程目录】

学习交流加&#xff08;可免费帮忙下载CSDN资源&#xff09;&#xff1a;个人微信(进微信群加)&#xff1a; LyyCoder学习交流资源分享qq群1&#xff08;已满&#xff09;&#xff1a; 962535112学习交流资源分享qq群2&#xff08;已满&#xff09;&#xff1a; 780902027学习交…

删除开机选择系统

在我的电脑点右键--属性--高级--系统启动,系统失败和调试信息--设置--显示操作系统列表时间,和在需要时显示恢复选项的时间,在前面的小方格里打上构或去掉构就行了. 修改引导分区里面的BOOT.INI文件s C:\boot.ini 将只读属性去掉 [boot loader] timeout30 defaultmulti(0)dis…

底层知识学习记录目录表

学习交流加&#xff08;可免费帮忙下载CSDN资源&#xff09;&#xff1a;个人微信(进微信群加)&#xff1a; LyyCoder学习交流资源分享qq群1&#xff08;已满&#xff09;&#xff1a; 962535112学习交流资源分享qq群2&#xff08;已满&#xff09;&#xff1a; 780902027学习交…

cdn加载vue很慢_Vue.js 项目打包优化实践

首先上结果&#xff1a;把常用的 Vue&#xff0c;router&#xff0c;vuex&#xff0c;axios 的 runtime 包拆分了出来&#xff0c;改为 cdn&#xff1b;另外就是对于自己编写的业务代码进行分包&#xff0c;根据路由进行懒加载&#xff0c;可以较好的提高首屏加载速度。添加了全…