程序员开发实例大全宝库

网站首页 > 编程文章 正文

仅凭一条SQL,领悟MySQL的全貌(一条sql只能使用一个索引吗)

zazugpt 2024-10-09 22:39:58 编程文章 13 ℃ 0 评论

MySQL 逻辑架构概览:



连接层(Connection Layer)负责建立、管理和终止客户端与MySQL服务器之间的连接。它主要处理与客户端的连接请求,验证客户端的身份(例如用户名、密码和来源IP等),并授权客户端访问数据库。一旦身份验证通过,连接层会为客户端创建一个新的线程,并为其提供服务。

MySQL 连接层为客户端程序提供到 MySQL 服务器的连接。连接会做两件事情,一个是管理 MySQL 连接,一个是权限验证。

shell> mysql -h 127.0.0.1 -u user -p
Enter password: aaaaaa
#密码一定要对额

通过上述命令完成经典的 TCP 三次握手建立连接后,

1、连接层就会根据你输入的用户名和密码来认证你的身份:

1)如果用户名或密码错误,收到一个 "Access denied for user" 的错误,然后客户端程序直接返回

2)如果用户名密码认证通过,会显示:

全文根据该SQL语句来分析:

mysql> select TENANT_ID ,DEPLOYMENT_ID from act_ext_model aem where id = 1684106845842649089;

2、验证该用户是否具有执行某个特定查询的权限(例如,是否允许该用户对 user 数据库的 table 表执行 SELECT 语句)。之后连接里面的所有权限判断逻辑,都将依赖于此时读到的权限。

3、当用户成功建立连接后,即使你在另一个终端用管理员账号对这个用户的权限做了修改,对当前已经存在连接的权限不会造成任何影响。当修改了用户权限后,只有再新建的连接才会使用新的权限设置。当一个连接建立起来后,如果你没有后续的动作,那么这个连接就处于空闲状态(Sleep)。

对于一个 MySQL 连接来说(或者说一个线程),任何时刻都有一个状态状态表示了 MySQL 当前正在做什么。用SHOW FULL PROCESSLIST 命令于显示当前在MySQL服务器上运行的所有进程或查询。可以查看当前正在执行的查询、执行的用户、查询的状态以及已经运行的时间等信息。

当你执行 SHOW FULL PROCESSLIST 命令时,会看到查询列表中的每个查询后面都有一个状态,例如 "Sleep"、"Query"、"Sending data" 等。这些状态表示查询当前正在执行的操作。

  • "Sleep":表示查询正在等待用户交互。
  • "Query":表示查询正在执行。
  • "Sending data":表示查询正在发送数据到客户端。
  • "Updating":表示查询正在更新数据。
  • "Flushing disk":表示查询正在将数据刷新到磁盘。

4、在MySQL中,默认的空闲连接超时时间取决于wait_timeout系统变量的值。如果未指定,则默认值通常为28800秒(8小时)。如果一个客户端连接到MySQL服务器后没有任何活动超过这个时间,连接将会被自动关闭。

#查看默认空闲连接超时时间
SHOW GLOBAL VARIABLES LIKE 'wait_timeout';
#设置默认空闲连接超时时间
SET GLOBAL wait_timeout = 300;  -- 设置超时时间为300秒

解析层(Parsing Layer)MySQL接收到客户端发送的SQL查询语句,然后进行解析。它使用解析器将SQL查询语句转换成抽象语法树(AST)。AST是SQL查询语句的树形表示,可以用于后续的查询优化和执行。

  • 接收查询:当客户端发送SQL查询语句给MySQL服务器时,MySQL首先接收到这个查询。
#接收到的语句
select TENANT_ID ,DEPLOYMENT_ID from act_ext_model 
aem where id = 1684106845842649089;
  • 词法分析:MySQL的解析器会对查询进行词法分析。这一步会将原始的SQL查询语句分解为一系列的“词法单元”或“token”。例如,关键字(如SELECT、FROM)、标识符(如表名或列名)、操作符(如=、<、>)等都会被识别出来。
词法分析,生成词法单元:select ,from,act_ext_model 
aem ,where ,=, id
  • 语法分析:在词法分析之后,解析器会进行语法分析。这一步会检查SQL查询语句的语法是否正确。例如,它会检查SELECT子句中的列名是否都在FROM子句中指定的表中,以及WHERE子句中的条件是否有效等。
  • 生成抽象语法树(AST):如果SQL查询语句的语法是正确的,解析器就会将其转换成抽象语法树(AST)。AST是一个树形结构,它表示了SQL查询语句的逻辑结构。每一个节点都代表了一个SQL语句的组成部分,如SELECT、FROM、WHERE等子句。

1、为了生成一个抽象语法树(AST),首先需要将给定的SQL查询语句分解为它的组成部分。下面是该查询的分解:

2、基于上述分解,构建一个简单的AST。请注意,实际的AST可能会根据具体的SQL解析器实现有所不同,但基本结构应该是相似的。以下是一个简化的AST表示:

SELECT  
    - TENANT_ID  
    - DEPLOYMENT_ID  
FROM  
    - act_ext_model (aem)  
WHERE  
    - id = 1684106845842649089

预处理层(Preprocessing Layer)MySQL对AST进行语义分析和处理,例如类型检查、视图处理和存储过程调用等。它还进行权限验证,确保客户端具有执行查询的必要权限。

  • 类型检查:MySQL会检查TENANT_ID和DEPLOYMENT_ID的数据类型,以及id的约束条件,确保查询中的数据类型与表结构中的定义相匹配。
  • 视图处理:如果act_ext_model是一个视图,预处理层会进行相应的视图解析,将原始的查询转换为对基础表的查询。
  • 权限验证:预处理层还会验证客户端是否有权限执行该查询。例如,它会检查当前用户是否具有从act_ext_model表中读取数据的权限。
  • 存储过程调用:如果查询中涉及到存储过程,预处理层会解析并调用这些存储过程。
  • 其他语义分析:预处理层还会进行其他语义相关的检查,例如检查是否存在未使用的列、函数或表达式等。

优化层(Optimization Layer)MySQL优化器会对AST进行优化,以提高查询性能。优化器会根据查询的具体情况选择合适的执行计划,并生成优化后的AST。它还考虑查询缓存的使用,如果查询结果已经缓存,则直接返回缓存结果,避免重复计算。

  • 使用主键索引:由于id是主键,优化器会优先使用主键索引来执行查询。主键索引通常提供了快速的行定位能力,能够大大提高查询的效率。
  • 减少检索的列数:由于查询只选择了TENANT_ID和DEPLOYMENT_ID两列,优化器会确保只检索这两列的数据,而不是检索整行数据。这有助于减少数据传输的开销。
  • 限制结果集大小:由于id是主键,并且您已经指定了一个具体的值,优化器可以快速定位到对应的行。因此,结果集的大小是已知的,并且非常小。这有助于减少内存的使用和磁盘I/O操作。
  • 其他优化:优化器还可能考虑其他与查询相关的因素,例如统计信息、表的大小和结构等,以进一步优化查询性能。

执行层(Execution Layer)MySQL将优化后的AST转换成可执行的查询计划,并执行查询。它与存储引擎层交互,获取或修改数据。执行层还处理事务和锁的相关操作。

  • 利用主键索引进行快速查找:由于id是主键,表act_ext_model中应该有一个相应的主键索引。执行层会利用这个主键索引来快速定位具有特定id值的行,从而减少扫描的行数,提高查询效率。
  • 与存储引擎交互:执行层会与存储引擎层交互,通过主键索引直接访问数据,快速获取TENANT_ID和DEPLOYMENT_ID列的值,而不需要全表扫描。这样可以减少I/O操作和数据读取的时间。
  • 处理事务和锁:如果该查询是事务的一部分,执行层会处理与事务相关的事务控制语句(如BEGIN、COMMIT、ROLLBACK等)和锁操作。由于这是一个简单的查询操作,不太可能涉及复杂的事务或锁处理。
  • 结果返回:一旦从存储引擎检索到数据,执行层会将结果集返回给客户端。在这个查询中,结果将包括满足条件的TENANT_ID和DEPLOYMENT_ID列的值。
  • 错误处理和异常处理:在执行查询过程中,执行层还会处理任何可能发生的错误或异常情况,例如数据类型不匹配、访问权限问题等。

存储引擎层(Storage Engine Layer)负责数据的存储和检索。MySQL支持多种存储引擎,每种存储引擎都有其特点和适用场景。常见的存储引擎包括InnoDB、MyISAM、Memory等。存储引擎与MySQL服务器进行通信,完成数据的存取操作。

  • 使用主键索引定位数据:存储引擎层会利用主键索引来快速定位具有特定id值的行。主键索引提供了快速的行定位能力,能够大大提高数据检索的效率。
  • 数据读取:一旦定位到相应的行,存储引擎层将从数据文件中读取TENANT_ID和DEPLOYMENT_ID列的值。对于InnoDB等支持事务的存储引擎,过程是原子性的,确保数据的一致性。
  • 返回结果:读取到数据后,存储引擎层将数据返回给执行层。执行层随后将结果集返回给客户端。
  • 错误处理和异常处理:在数据读取过程中,存储引擎层还会处理任何可能发生的错误或异常情况,例如数据损坏、磁盘空间不足等。这些错误和异常可能通过执行层的错误消息传递给客户端。
  • 事务和锁管理:如果该查询是事务的一部分,存储引擎层还负责管理事务的提交和回滚操作,以及与事务相关的锁操作。InnoDB等支持事务的存储引擎会在此层进行这些操作。

MySQL 的可插拔存储引擎架构是其最重要和与众不同的特性之一。这种架构允许开发者根据应用程序的需求选择适合的存储引擎,同时无需对应用程序代码进行任何更改。这种灵活性使得 MySQL 能够适应各种不同的使用场景,从高性能的在线事务处理(OLTP)到大数据仓库和数据挖掘等。

MySQL 的可插拔存储引擎架构允许不同的存储引擎提供不同的数据存储方式、索引类型、锁定水平以及其它底层系统功能。例如,InnoDB 存储引擎提供了事务支持、行级锁定和外键约束,而 MyISAM 存储引擎则提供了全文索引、高速缓存和更简单的查询处理。

架构的好处在于如果应用程序需要更改底层存储引擎,或者需要添加新的存储引擎来支持新的需求,那么这些更改可以在不修改应用程序代码的情况下进行。这大大简化了应用程序的开发和维护过程,同时也使得 MySQL 能够在不断发展的技术环境中保持竞争力。

系统基础设施(System Infrastructure)-硬件包括MySQL服务器所需的各种组件和功能,例如内存管理、线程管理、日志记录、复制和备份等。这些组件为整个MySQL系统的正常运行提供支持。

查询缓存(Query Cache)

最后介绍一下查询缓存。MySQL 5.7.20之前的版本查询缓存存储了 SELECT 语句的文本以及响应给客户端的相应结果。如果服务器稍后接收到相同的 SELECT 语句,服务器会先从查询缓存中检索结果,而不是再次解析和执行该语句。查询缓存在 session 之间共享,因此可以发送一个客户端生成的结果集以响应另一个客户端发出的相同查询。

如果当前的查询恰好命中了查询缓存,那么在返回查询结果之前 MySQL 会检查一次用户权限。这仍然是无须解析查询SQL语句的,因为在查询缓存中已经存放了当前查询需要访问的表信息。然而从 MySQL 5.7.20 开始,官方不再推荐使用查询缓存,并在 MySQL 8.0 中直接删除了查询缓存!

为什么查询缓存被废弃?看看这些场景

  • 查询缓存对频繁更新的数据库表可能不是很有效,因为每次表的内容发生变化时,相关的查询缓存都需要被清除。
  • 在某些情况下,查询缓存可能会导致性能问题,例如在高并发写入的情况下,因为每次写入都需要清除相关的查询缓存。
  • 查询缓存的大小应该根据实际需求进行调整,过大的缓存大小可能会导致内存使用过高。

对于MySQL 8.0之前的版本来说,可以将参数 query_cache_type 设置成 DEMAND,这样所有的 SQL 语句都不会再使用查询缓存。而对于你确定要使用查询缓存的语句,可以用 SQL_CACHE 显式指定,像下面这个语句一样:

mysql> select SQL_CACHE TENANT_ID ,DEPLOYMENT_ID
from act_ext_model aem where id = 1684106845842649089;

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表