数据库查询语句执行原理
当程序猿输入一条查询语句的时候,具体MySQL数据库是如何处理的呢?如何使其能达到更快更好的查询呢?接下来这篇文章将为你解释这个原理。
1. 基本路线
首先假定我们使用了一个应用程序,那么程序猿们先在应用程序上打入了一段SQL代码...
1.1 获取连接
应用程序先调用连接驱动,连接驱动通过网络连接到数据库服务端。数据库服务端收到连接请求,将请求信息发送给连接池管理器。连接池管理器从连接池中获取一个连接并将连接分配给请求。如果连接池中没有可用的连接,则等待或者创建一个新的连接。其运行流程如下
- 连接驱动从连接池获取一个连接(连接池负责管理一组可用的连接,并在需要时将其提供给应用程序)
1.2 连接驱动与连接池
建立了连接后,应用程序向连接驱动发送SQL查询语句,通过连接驱动与数据库的连接池交换数据,运行流程如下:
- 应用程序使用连接驱动程序发送SQL查询语句到数据库,并等待数据库的响应。
除此之外,我们还要注意,连接驱动发送的数据采用的是半双工模式通信(双方可以发送和接收信息,但不能同时进行发送和接收),也就是采用数据包的形式来进行传输,并且数据包的大小可以更改,如果查询语句超过上限则服务端拒绝接受,抛出异常。## 1.3 查询缓存(基本没啥用,带不来实质的效率提升)
查询缓存在5.7版本是默认关闭的,8.0版本则删除了查询缓存,因此并不需要记住多少。
当连接池中的某个连接需要执行一个查询时,连接池会首先检查查询缓存中是否有该查询语句及其结果,如果有,则直接返回结果,而不必向数据库发送查询请求。
但也会占用一定的内存空间,并且在频繁更新数据时可能会导致缓存失效,从而降低查询性能。
1.4 交给sql解析器来对sql语言进行解析
接下来数据传输给了SQL解析器,其将用户输入的SQL语句进行语法分析和转换,将SQL语句解析为可执行的计划(Plan),并最终执行查询操作。SQL解析器可以分为三个部分:词法分析器、语法分析器和语义分析器。
- 词法分析器(Lexer):将SQL语句分解成一个个Token,Token是SQL语句中最基本的单元,如SELECT、FROM、WHERE、GROUP BY等关键字,以及表名、列名、常量等。词法分析器会把Token按照语法分类,如关键字、标识符、操作符、常量等等。
- 语法分析器(Parser):将Token按照SQL语法进行组织,转换成语法树(Parse Tree)。语法树是一个有根节点、每个节点有零个或多个子节点的树状结构,它反映了SQL语句的语法结构,可以用于查询优化和执行计划生成。
- 语义分析器(Semantic Analyzer):在语法树的基础上,进行语义分析,检查SQL语句的正确性。例如,检查表名和列名是否存在,检查数据类型是否匹配等。
SQL解析器的主要作用是将SQL语句解析为可执行的计划,这个计划包含了如何获取和处理数据的具体步骤,如何使用索引、如何执行聚合函数等。SQL解析器的性能对整个数据库系统的性能影响很大,因此SQL解析器也是优化数据库性能的重要手段之一。
1.5 通过预处理器将请求进行拆分
当处理完成的查询语句进入预处理器后,由于连接复用的存在,多个应用程序线程会共享同一个数据库连接,每次使用前需要对 SQL 查询语句进行编译和解析,这个过程会消耗一定的时间和资源。
注:连接复用是指在数据库连接池中,当一个客户端完成一次数据库查询后,连接并不会被立即关闭,而是保留在连接池中,以备后续的数据库查询使用。这样可以减少数据库连接的创建和关闭次数,提高数据库查询的性能。
1.6 优化sql语言(优化器详细说明)
优化器会对该查询进行分析,找出执行该查询的最优执行计划,也就是访问数据库中数据的最佳方式。优化器通过对查询语句的语法树进行分析,找出查询中涉及的所有表、索引以及其他相关信息,并根据这些信息生成一个执行计划。执行计划中包含了执行查询所需的操作,例如扫描表、使用索引、排序等。
优化器的主要任务是确定执行计划中每个操作的执行顺序和方式,以及选择合适的算法和数据结构来实现查询,从而使查询能够在最短的时间内返回结果。
SQL优化器的作用是优化查询语句的执行计划,但是它并不负责查询语句的语义分析。因此,即使优化器生成了最优的执行计划,但如果查询语句的语义不正确,也会导致查询结果不正确。
1.7 执行器
最终的优化结果传输到执行器按照执行计划逐步执行SQL语句,包括打开数据表、读取数据、执行计算、更新数据、关闭数据表等步骤,最终将结果返回给用户。在执行的过程中,执行器需要与存储引擎模块协同工作,通过存储引擎模块提供的API来操作数据表。执行器还负责处理事务、锁定等并发控制机制,保证数据库的一致性和隔离性。
查询语句的结果会由执行器将查询结果反馈给连接池。具体来说,当执行器执行完查询语句后,会将查询结果打包成数据包,然后将数据包发送给连接池。连接池在接收到数据包后,会将数据包转发给应用程序。应用程序可以根据需要对查询结果进行处理和展示。
1.8 Handler API
终于到了最后,经历过一些列复杂的过程,将命令传输到了 Handler API,程序猿们终于能拿到香蕉(笑)通过HandlerAPI,可以实现基本的增、删、改、查操作,以及锁定和解锁表、读取和写入数据等操作。它提供了一系列函数,可以按照指定条件访问表中的数据行,还可以进行分组、排序、聚合等操作,支持事务的提交、回滚等。
1.9 流程图
最终来一张流程图收尾。