Mysql8应用架构

Mysql8应用架构

一、应用架构图

Mysql将数据的存取和SQL的处理进行了有效的划分。针对于SQL交给了计算层,而针对于数据的存取(入和出)交给了存储引擎层。

二、执行顺序

大白话方式

当JAVA程序集成了Mysql的应用客户端、或者使用Mysql Shell指令和Mysql服务器进行交互。当我们把SQL语句投递给Mysql服务器的时候,Mysql的服务器处理器(mysqld) ,首先将SQL投递给SQL Interface (用于接收外界传递进来的SQL语句,最后在存储引擎查到的结果也由SQL Interface返回给客户端),接着会将SQL送入到Parser(SQL分析(解析)器: 按照AST语法树格式,转换为Mysql内部可以处理识别的对象),然后到优化器 (主要职责是根据现有的数据的环境和现有的语法特点来看是否有更好的执行计划**。** 优化器决定了程序的好和坏,但是是在程序执行之前进行分析的,并不代表最终的效果。)最后是Caches&Buffers 。在Mysql5中Query Cache存在,在Mysql8中没有。查询缓存对于空间浪费较大,命中率较低。但仍然有全局缓存,比如应用程序中的一些共性的数据,同时针对不同的存储引擎,也有自己的缓存池。(InnDB中有Cache Buffer Pool)。最后一个组件是NoSQL,主要是对JSON结构的数据进行支持,相关JSON的数据交给NoSQL处理。

1.SQL Interface(SQL接口)

  • SQL接口是MySQL服务器与客户端交互的入口,负责接收客户端发送的SQL语句,并将最终的执行结果返回给客户端。

  • 无论是Java应用程序、MySQL Shell还是其他客户端工具,都会通过SQL接口与MySQL服务器通信。

2.Parser(解析器)和预处理器

  • 解析器的作用是将SQL语句转换为MySQL内部可以识别的结构(通常是抽象语法树,AST)。

  • 解析器会检查SQL语句的语法是否正确。如果语法错误,会直接返回错误信息给客户端。

  • 解析后的SQL语句会被转换为MySQL内部的查询表示形式,供后续组件处理。

首先,MySQL的解析器将查询分解成标记,并从中构建"解析树"。解析器使用MySQL的SQL语法来解释和验证查询,例如验证未终止的引号字符串,检查表和列是否存在等。接下来,预处理器会检查权限。通常,这很快,除非您的服务器有大量权限。

3.Optimizer(优化器)

  • 优化器的主要职责是生成执行计划(Execution Plan),即决定如何高效地执行SQL语句。

  • 优化器会考虑多种因素,例如:

    • 表的索引情况。

    • 表的大小。

    • 查询条件的选择性。

    • 可能的连接顺序(对于多表查询)。

  • 优化器会选择一个它认为最优的执行计划,但这个计划并不一定总是最好的,因为优化器是基于统计信息和规则进行估算的。

  • 优化器的决策会影响查询的性能,因此优化器的质量对数据库性能至关重要。

现在解析树已经有效,优化器可以将其转换为查询执行计划。一个查询可以以多种不同的方式执行并产生相同的结果。优化器的工作是找到最佳选项。

MySQL使用基于代价的优化器,这意味着它试图预测各种执行计划的代价并选择最便宜的选项。

它基于统计数据来估算:每个表或索引的页面数、索引的基数(不同值的数量)、行和键的长度以及键分布。优化器不包括任何类型的缓存效果在其估算中-它假设每个读取都将导致磁盘I/O操作。

优化器可能并不总是选择最佳的计划,原因有很多:

  • 统计数据可能是错误的。服务器依赖存储引擎提供统计数据,它们的准确性可能从非常正确到极其不准确。例如,由于其MVCC架构,InnoDB存储引擎无法维护关于表中行数的准确统计信息。
  • 成本度量标准并不完全等同于运行查询的真实成本。它可能比MySQL的近似值更昂贵或更便宜。例如,当MySQL不知道哪些页面在内存中,哪些页面在磁盘上时,它实际上不知道查询将导致多少I/O。
  • 您可能希望获得最快的执行时间,但MySQL并不真正尝试使查询快速,而是尝试将其成本最小化。
  • 优化器并不总能估计每个可能的执行计划,因此可能会错过最佳计划。

MySQL的查询优化器可以应用静态优化,例如独立于值的优化,例如WHERE子句中的常量值。它们可以执行一次,并且在重新执行查询时始终有效。

相比之下,动态优化基于上下文,可以取决于许多因素,例如WHERE子句中的值或索引中的行数。每次执行查询时都必须重新评估它们。您可以将它们视为"运行时优化"。

MySQL知道如何自行执行许多优化,例如重新排序连接、转换连接、应用代数等价规则、COUNT()、MIN()和MAX()优化、子查询优化等等。

4.查询执行引擎

解析和优化阶段输出查询执行计划,Mysql的查询执行引擎使用它来处理查询。

和优化阶段相比,执行阶段通常不复杂,Mysql只需按照查询执行计划中给出的指令进行操作。计划中的许多操作调用由存储引擎实现的方法,也称为处理程序API。

向客户端返回结果

执行查询的最后一步是向客户端回复。即使不返回结果集的查询也会向客户端连接回复有关查询的信息,比如它影响了多少行。

如果查询是可缓存的,Mysql也会在此阶段将结果放入查询缓存中。

5.存储引擎层

它们负责存储和检索Mysql中存储的所有数据。它们是以插件的形式实现的,这使得相对容易实现不同的数据处理方式。

主要的存储引擎是InnoDB,是完全事务性的,并具有非常好的支持高并发工作负载的能力。

另一个存储引擎示例是NDBCluster,它也是事务性的,并作为MySQL NDB Cluster的一部分使用。

优化器并不在意一个特定表使用哪个存储引擎,但存储引擎确实会影响服务器优化查询的方式。优化器会向存储引擎询问一些操作的成本和能力,以及表数据的统计信息。

存储引擎本身可能也很复杂。对于InnoDB,它包括用于缓存数据和索引的缓冲池、重做和撤销日志、其他缓冲区以及表空间文件。如果查询返回行,这些行将从存储引擎通过SQL层发送回应用程序。

但在解析查询之前,服务器会先查询查询缓存,其中只存储SELECT语句及其结果集。如果有人发出的查询与缓存中已有的查询完全相同,则服务器根本不需要解析、优化或执行查询,它只需返回存储的结果集即可。

在查询调优中,优化器和执行步骤,包括存储引擎,是最重要的步骤。本指南中的大部分信息都与这三个部分直接或间接相关。

InnoDB引擎是一个通用的存储引擎,平衡了高可靠性和高性能,它被设计用于处理许多短暂的事务。除非有强烈的理由使用其他引擎,否则应该为表使用InnoDB。

InnoDB表是建立在聚集索引上的,聚集索引是InnoDB用于组织数据的术语。该名称来自于索引值聚集在一起的事实。在InnoDB中,一切都是索引。行数据位于B树索引的叶子页面中。

主键用于聚集索引。如果你没有明确指定主键,InnoDB将寻找一个不允许NULL值的唯一索引。如果也不存在这样的索引,则InnoDB将添加一个隐藏的6字节整数列,使用全局(适用于所有InnoDB表)自增值来生成一个唯一值。

因此,它提供了非常快的主键查找。但是,次要索引(不是主键的索引)包含主键列,因此如果你的主键很大,其他索引也将很大。如果在表上有许多索引,应该力求使主键小。

三、总结

一、Caches & Buffers(缓存和缓冲)

Query Cache(查询缓存,MySQL 5.x中存在,MySQL 8.x中已移除)

  • 查询缓存的作用是缓存查询语句及其结果。如果后续有相同的查询语句,MySQL会直接从缓存中返回结果,而不需要重新执行查询。

  • 查询缓存的命中率通常较低,尤其是在写频繁的场景中,因为任何对表的修改都会导致相关缓存失效。由于这些问题,MySQL 8.x移除了查询缓存。

Buffer Pool(缓冲池,InnoDB存储引擎)

  • InnoDB的缓冲池是MySQL中最重要的缓存之一,用于缓存表和索引数据。

  • 缓冲池的大小可以通过参数innodb_buffer_pool_size配置,较大的缓冲池可以提高查询性能。

二、NoSQL支持(JSON数据处理)

  • 从MySQL 5.7开始,MySQL增加了对JSON数据类型的支持,并提供了相关的函数和操作符。

  • JSON数据存储在表中时,会被当作一种特殊的数据类型处理。

  • MySQL提供了对JSON数据的查询、更新和索引支持,但这些操作仍然是通过SQL接口和存储引擎完成的,而不是通过独立的NoSQL接口。NoSQL在MySQL中的作用可以理解为提供了对JSON数据的存储和操作支持。

相关推荐
鲤籽鲲4 分钟前
C# ManualResetEvent 类 使用详解
java·开发语言·c#·多线程
我没想到原来他们都是一堆坏人18 分钟前
在微服务中,如何使用feign在各个微服务中进行远程调用
微服务·云原生·架构
硬件人某某某29 分钟前
微信小程序~电器维修系统小程序
java·ajax·微信小程序·小程序
猿java31 分钟前
MySQL 如何实现主从复制?
java·后端·mysql
martian66541 分钟前
【Java基础篇】——第4篇:Java常用类库与工具类
java·开发语言
violin-wang1 小时前
Intellij IDEA调整栈内存空间大小详细教程,添加参数-Xss....
java·ide·intellij-idea·xss·栈内存·栈空间
在下陈平安1 小时前
java-LinkedList源码详解
java·开发语言
黑客老李1 小时前
一次使用十六进制溢出绕过 WAF实现XSS的经历
java·运维·服务器·前端·sql·学习·xss
Mao.O1 小时前
IDEA编写SpringBoot项目时使用Lombok报错“找不到符号”的原因和解决
java·spring boot·intellij-idea·lombok
AAA码农烧烤2 小时前
微服务..
微服务·云原生·架构