MySQL性能优化(一)MySQL中SQL语句是如何执行的?

该篇章将开始整理MySQL的优化,不过开始之前,我们想了解清楚那就是MySQL是怎么执行的。

文章目录

  • 1.MySQL驱动
  • 2.应用系统数据库连接池
  • 3.MySQL数据库连接池
  • 4.SQL执行过程
    • 4.1.线程监听:监听网络请求中的SQL语句
    • 4.2.SQL接口:负责处理接收到的SQL语句
    • 4.3.查询解析器:让MySQL能看懂SQL语句
    • 4.4.查询优化器:选择最优的查询路径
    • 4.5.存储引擎接口:真正执行SQL语句
    • 4.6.执行器:根据执行计划调用存储引擎的接口
  • 5.总结

1.MySQL驱动

大家都知道,我们如果要在Java系统中去访问一个MySQL数据库,必须得在系统的依赖中加入一个MySQL驱动,有了这个MySQL驱动才能跟MySQL数据库建立连接,然后执行各种各样的SQL语句。
MySQL驱动,他会在底层跟数据库建立网络连接,有网络连接,接着才能去发送请求给数据库服务器!当我们跟数据库之间有了网络连接之后,我们的Java代码才能基于这个连接去执行各种各样的增删改查SQL语句。
在这里插入图片描述

2.应用系统数据库连接池

假设我们的系统是部署在Tomcat中的,那么Tomcat本身肯定是有多个线程来并发的处理同时接收到的多个请求的,如果Tomcat中的多个线程并发处理多个请求的时候,都要去抢夺一个连接去访问数据库的话,那效率肯定是很低下的。
在这里插入图片描述

如果Tomcat中的每个线程在每次访问数据库的时候,都基于MySQL驱动去创建一个数据库连接,然后执行SQL语句,然后执行完之后再销毁这个数据库连接,可能Tomcat中上百个线程会并发的频繁创建数据库连接,执行SQL语句,然后频繁的销毁数据库连接,也是非常不好的,因为每次建立一个数据库连接都很耗时,好不容易建立好了连接,执行完了SQL语句,你还把数据库连接给销毁了,下一次再重新建立数据库连接,那肯定是效率很低下的!
在这里插入图片描述
所以一般我们必须要使用一个数据库连接池,也就是说在一个池子里维持多个数据库连接,让多个线程使用里面的不同的数据库连接去执行SQL语句,然后执行完SQL语句之后,不要销毁这个数据库连接,而是把连接放回池子里,后续还可以继续使用。基于这样的一个数据库连接池的机制,就可以解决多个线程并发的使用多个数据库连接去执行SQL语句的问题,而且还避免了数据库连接使用完之后就销毁的问题。
常见的数据库连接池有DBCP,C3P0,Druid
在这里插入图片描述

3.MySQL数据库连接池

任何一个系统都会有一个数据库连接池去访问数据库,也就是说这个系统会有多个数据库连接,供多线程并发的使用。同时我们可能会有多个系统同时去访问一个数据库,这都是有可能的。MySQL也必然要维护与系统之间的多个连接。

实际上MySQL中的连接池就是维护了与系统之间的多个数据库连接。除此之外,你的系统每次跟MySQL建立连接的时候,还会根据你传递过来的账号和密码,进行账号密码的验证,库表权限的验证。
在这里插入图片描述

4.SQL执行过程

4.1.线程监听:监听网络请求中的SQL语句

现在假设我们的数据库服务器的连接池中的某个连接接收到了网络请求,假设就是一条SQL语句,那么大家先思考一个问题,谁负责从这个连接中去监听网络请求?谁负责从网络连接里把请求数据读取出来?
我想很多人恐怕都没思考过这个问题,但是如果大家对计算机基础知识有一个简单了解的话,应该或多或少知道一点,那就是网络连接必须得分配给一个线程去进行处理,由一个线程来监听请求以及读取请求数据,比如从网络连接中读取和解析出来一条我们的系统发送过去的SQL语句,如下图所示
在这里插入图片描述

4.2.SQL接口:负责处理接收到的SQL语句

当MySQL内部的工作线程从一个网络连接中读取出来一个SQL语句之后,此时会如何来执行这个SQL语
句呢?
MySQL内部首先提供了一个组件,就是SQL接口(SQL Interface),他是一套执行SQL语句的接口,专门用于执行我们发送给MySQL的那些增删改查的SQL语句。因此MySQL的工作线程接收到SQL语句之后,就会转交给SQL接口去执行,如下图:
在这里插入图片描述

4.3.查询解析器:让MySQL能看懂SQL语句

SQL接口怎么执行SQL语句呢?你直接把SQL语句交给MySQL,他能看懂和理解这些SQL语句吗?
比如我们来举一个例子,现在我们有这么一个SQL语句:

select id,name,age from users where id=1
1

MySQL自己本身也是一个系统,是一个数据库管理系统,他没法直接理解这些SQL语句!
所以此时有一个关键的组件要出场了,那就是查询解析器。

这个查询解析器(Parser)就是负责对SQL语句进行解析的,比如对上面那个SQL语句进行一下拆解,拆解成以下几个部分:

  1. 我们现在要从“users”表里查询数据(from users)
  2. 查询“id”字段的值等于1的那行数据(where id=1)
  3. 对查出来的那行数据要提取里面的“id,name,age”三个字段(select id,name,age)

所谓的SQL解析,就是按照既定的SQL语法,对我们按照SQL语法规则编写的SQL语句进行解析,然后理解这个SQL语句要干什么事情,如下图所示
在这里插入图片描述

4.4.查询优化器:选择最优的查询路径

当我们通过解析器理解了SQL语句要干什么之后,接着会找查询优化器(Optimizer)来选择一个最优的查询路径。
在语法分析阶段:会对SQL语句进行分析,比如如下sql语句

select A.name, A.age from tb_student A where A.age=18 and A.name='张三'
1

该SQL在被执行之前,会先进行语法检测,判断有无错误,之后会分析出如下两个sql查询条件,

  1. where A.age=18
  2. where A.name=‘张三’

问题就来了,这两个条件谁先执行有区别吗?答案是肯定的,在我们编写SQL的时候,都会遵循一个原则,就是把区分度最高的放在左侧。

  1. where A.name=‘张三’ AND A.age=18
  2. where A.age=18 AND A.name=‘张三’

上面这就是一个最简单的SQL语句的两种实现路径,其实我们会发现,要完成这个SQL语句的目标,两个路径都可以做到,但是哪一种更好呢?显然感觉上是第一种查询路径更好一些。因为在我们数据库系统中,叫张三的人可能只有几百个,但是年龄为18岁的,可能有几万个。

所以查询优化器大概就是干这个的,他会针对你编写的几十行、几百行甚至上千行的复杂SQL语句生成查询路径树,然后从里面选择一条最优的查询路径出来。相当于他会告诉你,你应该按照一个什么样的步骤和顺序,去执行哪些操作,然后一步一步的把SQL语句就给完成了。
在这里插入图片描述

4.5.存储引擎接口:真正执行SQL语句

把查询优化器选择的最优查询路径,也就是你到底应该按照一个什么样的顺序和步骤去执行这个SQL语句的计划,把这个计划交给底层的存储引擎去真正的执行。这个存储引擎是MySQL的架构设计中很有特色的一个环节。

真正在执行SQL语句的时候,要不然是更新数据,要不然是查询数据,那么数据你觉得存放在哪里?
以对数据库而言,我们的数据要不然是放在内存里,要不然是放在磁盘文件里。
在这里插入图片描述
那么现在问题来了,我们已经知道一个SQL语句要如何执行了,但是我们现在怎么知道哪些数据在内存里?哪些数据在磁盘里?我们执行的时候是更新内存的数据?还是更新磁盘的数据?我们如果更新磁盘的数据,是先查询哪个磁盘文件,再更新哪个磁盘文件?

所以这个时候就需要存储引擎了,存储引擎其实就是执行SQL语句的,他会按照一定的步骤去查询内存缓存数据,更新磁盘数据,查询磁盘数据,等等,执行诸如此类的一系列的操作,如下图所示。
在这里插入图片描述
存储引擎支持各种各样的存储引擎的,比如我们常见的InnoDB、MyISAM、Memory等等,我们是可以选择使用哪种存储引擎来负责具体的SQL语句执行的。当然现在MySQL一般都是使用InnoDB存储引擎。

4.6.执行器:根据执行计划调用存储引擎的接口

存储引擎可以帮助我们去访问内存以及磁盘上的数据,那么是谁来调用存储引擎的接口呢?
其实我们现在还漏了一个执行器的概念,这个执行器会根据优化器选择的执行方案,去调用存储引擎的接口按照一定的顺序和步骤,就把SQL语句的逻辑给执行了。

执行器就会去根据我们的优化器生成的一套执行计划,然后不停的调用存储引擎的各种接口去完成SQL
语句的执行计划,大致就是不停的更新或者提取一些数据出来。在这里插入图片描述

5.总结

本文介绍内容总体如下流程图所示
在这里插入图片描述

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

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

相关文章

2023_Spark_实验三十三:配置Standalone模式Spark3.4.2集群

实验目的:掌握Spark Standalone部署模式 实验方法:基于centos7部署Spark standalone模式集群 实验步骤: 一、下载spark软件 下载的时候下载与自己idea里对应版本的spark News | Apache Spark 选择任意一个下载即可 - spark 3.4.1 - spark …

MySQL性能优化(二)InnoDB之日志文件

文章目录1.MySQL日志记录文件1.1.回顾SQL语句的执行1.2.InnoDB内存结构:缓冲池1.3.记录日志:Undo和Redo1.3.1.Undo日志文件:记录数据修改前的值1.3.2.Redo日志文件:记录数据即将修改值1.3.3.Undo和Redo的区别(记录、前…

php正则检查QQ,PHP 正则匹配手机号的QQ号

//匹配手机号码//$mode /\d{3}-\d{8}|\d{4}-\d{7}|\d{11}/;//不匹配以-开头的手机号码//$mode /^((?!-).)*\d{3}-\d{8}|^((?!-).)*\d{4}-\d{7}|^((?!-).)*\d{11}/;//不匹配以 / 开头或结束的手机号码$mode /^((?!\/).)*\d{3}-\d{8}((?!\/).)*$|^((?!\/).)*\d{4}-\d{7}…

java获取单击内容,java – 单击菜单链接时,获取元素不是可点击的异常

我想点击菜单链接但没有运气.它总是显示异常 –Exception in thread “main” org.openqa.selenium.WebDriverException:unknown error: Element is not clickable at point (64, 64). Otherelement would receive the click: <div style”position: absolute; left:0px; to…

MySQL性能优化(三)Buffer Pool实现原理

文章目录1.回顾缓冲池 Buffer Pool2.配置Buffer Pool的大小3.Buffer Pool&#xff1a;数据结构3.1.磁盘数据结构&#xff1a;数据页3.2.缓冲池数据结构&#xff1a;数据页(缓存页)3.3.缓存页对应的描述信息4.Buffer Pool&#xff1a;初始化5.Buffer Pool&#xff1a;free链表6.…

MySQL性能优化(四)redo log实现原理

文章目录1.redo log的作用2.redo log的结构2.1.redo log 记录2.2.redo log block2.3.redo log buffer3.redo log buffer 刷盘1.redo log的作用 首先我们都知道&#xff0c;执行增删改SQL语句的时候&#xff0c;都是针对一个表中的某些数据去执行的&#xff0c;此时的话&#x…

MySQL性能优化(五)undo log是如何实现MVCC的?

之前我们最开始的几篇文章就讲过&#xff0c;你除了写redolog日志还必须要写undo log日志&#xff0c;这个undo log日志是至关重要的&#xff0c;没有他&#xff0c;你根本都没办法回滚事务&#xff01; 1.事务 1.1.多线程并发执行多个事务 对于我们的业务系统去访问数据库而…

Linux中Shell脚本--awk的用法

语法格式&#xff1a;awk [选项] ‘指令’ 操作文件 常用选项&#xff1a;-F 指定分隔符&#xff0c;分隔符用""引起来 -v&#xff1a;varvalue在awk程序开始之前指定一个值valu给变量var&#xff0c;这些变量值用于awk程序的BEGIN快 -f&#xff1a;后面跟一个保存…

linux下的shell脚本(基础)

Shell是一种脚本语言&#xff0c;那么&#xff0c;就必须有解释器来执行这些脚本&#xff0c;常见的脚本解释器有&#xff1a; bash&#xff1a;是Linux标准默认的shell。bash由Brian Fox和Chet Ramey共同完成&#xff0c;是BourneAgain Shell的缩写&#xff0c;内部命令一共有…

mysql rsync复制,mysql复制又同步

mysql复制再同步由于一个老旧系统没有使用LVM分区,导致mylvmbackup不能使用。为了重新全量同步数据库&#xff0c;发现rsync可以使用&#xff0c;并且锁住数据库的时间不长。1. 首先刷新数据库到文件flush tables with read lock;unlock tables;2. 执行rsync进行数据库同步/usr…

解决springboot中只支持get请求,无法支持post请求

解决springboot中只支持get请求&#xff0c;无法支持post请求 报错信息如下&#xff1a; 405 相关类如下&#xff1a; RestController RequestMapping public class HttpServiceController {Autowiredprivate HttpSecretReport httpSecretReport;Autowiredprivate HttpSecret…

mysql2005卸载步骤,二次安装mysql步骤

1.先将mysql服务停止&#xff0c;并关闭服务页面(否则后面报错&#xff1a;“指定的服务已经标记为删除”)&#xff1a;打开“任务管理器”可以找到服务页面2.在控制面板对mysql进行删除。找到并将其卸载&#xff0c;如果没有直接跳过3.在注册表中删除相关目录。(使用组合键&qu…

Spring Boot 默认数据源 HikariDataSource_Spring Boot 中使用 Hikari

Spring Boot 默认数据源 HikariDataSource springboot2.x之后&#xff0c;系统的默认数据源由原来的的org.apache.tomcat.jdbc.pool.DataSource更改为com.zaxxer.hikari.HikariDataSource。 HikariDataSource 号称 Java WEB 当前速度最快的数据源&#xff0c;相比于传统的 C3…

matlab取出等高线上的数据,在Python或MATLAB中从等高线图中提取数据

这是一个小型的Matlab脚本&#xff0c;可以完成这项工作(使用一些GUI&#xff0c;在图的斜角处读取guidlines)&#xff1a;%// Import the data:imdata importdata(your_picture_file);Gray rgb2gray(imdata.cdata);colorLim [-1 1]; %// this should be set manually%// Ge…

SpringBoot-默认数据源HikariDataSource对数据库操作及自动装配原理

默认数据源HikariDataSource对数据库操作 在创建项目时选择JDBC以及MySQL驱动&#xff0c;让SpringBoot自动装配所需组件 创建完成后默认的pom.xml文件如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.o…

matlab fgetl用法,Matlab fgetl strsplit 函数

函数功能&#xff1a;从文件中调用一行数据matlab中fgetl函数&#xff0c;并除去行末的换行符。语法格式&#xff1a;tline fgetl(fid)fid是通过fopen函数打开文件后得到的一个整型的文件标志。fgetl从这个文件中调用一行数据并丢弃其中的换行符。如果抓取成功tline容纳了调用…

HikariCP源码简洁剖析——HikariDataSource_HikariCP的使用和源码

文章目录HikariDataSource的作用源码剖析核心变量构造方法获取链接实例HikariCP的使用和源码简介HikariCP是什么&#xff1f;HikariCP 解决了哪些问题&#xff1f;为什么要使用 HikariCP&#xff1f;本文要讲什么&#xff1f;如何使用 HikariCP需求项目环境引入依赖编写 hikari…

MySQL如何创建沙箱,沙箱环境搭建 - osc_y8w65yuq的个人空间 - OSCHINA - 中文开源技术交流社区...

[toc]测试环境搭建沙箱环境&#xff1a;-------测试环境搭建基础配置&#xff1a;# 1、在沙箱环境下实名认证&#xff1a;https://openhome.alipay.com/platform/appDaily.htm?tabinfo# 2、电脑网站支付API&#xff1a;https://docs.open.alipay.com/270/105898/# 3、完成RSA密…

PHP单选框实现的方法,jQuery简单实现遍历单选框的方法

本文实例讲述了jQuery简单实现遍历单选框的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;1、问题背景&#xff1a;有四个单选框&#xff0c;分别为一年四季&#xff0c;现在需要判断是否选中&#xff0c;如果选中这个单选框&#xff0c;就将其值赋值给输入框2、…

String怎么转成BigDecimal_Java.math.BigDecimal类的使用

1.引言 浮点数值不适用于无法接受舍入误差的金融计算中。 例如&#xff0c;命令System.out.prmtln (2.0-1.1)将打印出0.8999999999999999&#xff0c;而不是人们想象的0.9 。 2.0-1.1的运算结果 这种舍入误差的主要原因是浮点数值采用二进制系统表示&#xff0c;而在二进制系统…