首页 数据库 mysql教程 SQL查询语句是如何执行的

SQL查询语句是如何执行的

Jan 01, 2025 am 05:49 AM

大家好!这是我的第一篇文章。

这篇文章我将介绍一条sql查询语句是如何执行的

下面是MySQL架构图:

How is an SQL Query Statement executed

总的来说,MySQl可以分为两部分:服务器层和存储引擎层。

服务器层包括连接器、查询缓存、解析器、优化器、执行器等,包含MySQL的大部分核心服务功能,以及所有内置功能(如日期、时间、数学和加密)功能)。所有跨存储引擎的功能,例如存储过程、触发器和视图都在这一层实现。

存储引擎层负责数据的存储和检索。其架构是基于插件的,支持InnoDB、MyISAM、Memory等多种存储引擎。从MySQL 5.5.5开始,InnoDB成为MySQL的默认存储引擎。

创建表时可以使用带有engine=memory的create table语句指定内存引擎。

不同的存储引擎共享同一个Server层

连接器

第一步是连接数据库,这需要连接器。连接器负责与客户端建立连接、获取权限并维护和管理连接。连接命令为:

mysql -h$ip -P$port -u$user -p
登录后复制
登录后复制

该命令用于与服务器建立连接。完成经典的 TCP 握手后,连接器将使用提供商的用户名和密码来验证您的身份。

  • 如果用户名或密码不正确,您将收到“用户错误导致访问被拒绝”的消息,并且客户端程序将终止。
  • 如果身份验证成功,连接器将从权限表中检索当前帐户的权限。此连接期间的所有权限检查都依赖于此初始检索。

这意味着一旦连接成功建立,管理员对用户权限所做的任何更改都不会影响现有连接的权限。只有新连接才会使用更新后的权限设置。

连接建立后,如果没有后续动作,则连接进入空闲状态,可以使用show processlist命令查看:

How is an SQL Query Statement executed

如果客户端长时间处于不活动状态,连接器将自动断开连接。持续时间由 wait_timeout 参数控制,默认为 8 小时。

如果连接终止并且客户端发送请求,则会收到错误消息:在查询期间丢失与 MySQL 服务器的连接。要继续,您需要重新连接,然后执行请求。

在数据库中,持久连接是指客户端在成功连接后为连续请求保持相同的连接。短连接是指在几次查询后断开连接并重新连接以进行后续查询。

由于连接过程比较复杂,建议开发过程中尽量减少连接的创建,即尽可能使用持久连接。

但是,当使用持久连接时,MySQL 的内存使用量可能会显着增加,因为执行期间使用的临时内存是在连接对象内管理的。仅当连接终止时,这些资源才会被释放。如果长连接不断累积,可能会导致内存使用过多,导致系统强行终止MySQL(OOM),导致意外重启。

解决方案

  1. 定期断开持久连接。使用连接一段时间或执行消耗过多内存的查询后,请断开连接并重新连接以进行后续查询。
  2. 如果您使用的是 MySQL 5.7 或更高版本,您可以在执行资源密集型操作后使用 mysql_reset_connection 来重新初始化连接资源。此过程不需要重新连接或重新验证,而是将连接重置为刚刚创建的状态。

查询缓存

注意:从 MySQL 8.0 开始,查询缓存功能已被完全删除,因为其弊大于利

当MySQL收到查询请求时,它首先检查查询缓存,看看这个查询之前是否已经执行过。之前执行过的查询及其结果以键值对的形式缓存在内存中。键是查询语句,值是结果。如果在查询缓存中找到该键,则将该值直接返回给客户端。

如果在查询缓存中未找到查询,则过程继续。

为什么查询缓存弊大于利?

查询缓存失效的情况非常频繁地发生。对表的任何更新都会清除与该表相关的所有查询缓存,导致缓存命中率非常低,除非该表是静态配置表。

MySQL提供了一种“按需”的方法来使用查询缓存。通过将参数query_cache_type设置为DEMAND,SQL语句默认不会使用查询缓存。要使用查询缓存,可以显式指定 SQL_CACHE:

mysql -h$ip -P$port -u$user -p
登录后复制
登录后复制

解析器

如果查询缓存没有命中,则语句执行过程开始。 MySQL 首先需要了解要做什么,因此它会解析 SQL 语句。

解析器首先执行词法分析。输入的 SQL 语句由字符串和空格组成,MySQL 会对其进行分析,以识别每个部分代表的含义。例如select标识为查询语句,T标识为表名,ID标识为列。

词法分析之后,进行语法分析。语法分析器根据词法分析的结果判断SQL语句是否符合MySQL的语法规则。

如果存在语法错误,将会显示类似“您的 SQL 语法有错误”的错误消息。例如,在以下查询中,select 关键字拼写错误:

select SQL_CACHE * from T where ID=10;
登录后复制

优化器

解析之后,MySQL 知道你想做什么。接下来,优化器确定如何执行。

当一个表有多个索引时,优化器决定使用哪个索引,或者当查询涉及多个表时,优化器决定表连接的顺序。例如,在以下查询中:

mysql> elect * from t where ID=1;

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'elect * from t where ID=1' at line 1
登录后复制

查询可以从检索 t1 或 t2 中的值开始。两种方法产生相同的逻辑结果,但它们的性能可能不同。优化器的作用是选择最有效的计划。

优化阶段结束后,流程进入执行器。

执行者

执行器开始执行查询。

执行前,首先检查当前连接是否有查询表的权限。如果没有,则返回错误,指示权限不足。 (从查询缓存返回结果时也会执行权限检查。)

如果授予权限,则打开表并继续执行。在此过程中,执行器根据表的引擎定义与存储引擎进行交互。

例如,假设表 T 在 ID 列上没有索引。执行者的执行过程如下:

  1. 调用InnoDB引擎接口取出表的第一行,检查ID值是否为10,如果不是则跳过;如果是,则将其添加到结果集中。
  2. 调用引擎接口获取“下一行”,重复相同的逻辑,直到检查完所有行。
  3. 执行器将累积的结果集返回给客户端。

至此,查询完成。

对于索引表,该过程涉及使用引擎的预定义方法来迭代获取“第一个匹配行”和“下一个匹配行”。

慢查询日志中,rows_examined字段表示查询执行过程中扫描的行数。每次执行器调用引擎检索数据行时,该值都会累加。

在某些情况下,对执行器的单次调用可能涉及在引擎内部扫描多行。因此,引擎扫描的行数不一定等于 rows_examined.

结尾

感谢您的阅读!希望文章对您有所帮助。

以上是SQL查询语句是如何执行的的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

减少在Docker中使用MySQL内存的使用 减少在Docker中使用MySQL内存的使用 Mar 04, 2025 pm 03:52 PM

减少在Docker中使用MySQL内存的使用

如何使用Alter Table语句在MySQL中更改表? 如何使用Alter Table语句在MySQL中更改表? Mar 19, 2025 pm 03:51 PM

如何使用Alter Table语句在MySQL中更改表?

mysql无法打开共享库怎么解决 mysql无法打开共享库怎么解决 Mar 04, 2025 pm 04:01 PM

mysql无法打开共享库怎么解决

在 Linux 中运行 MySQl(有/没有带有 phpmyadmin 的 podman 容器) 在 Linux 中运行 MySQl(有/没有带有 phpmyadmin 的 podman 容器) Mar 04, 2025 pm 03:54 PM

在 Linux 中运行 MySQl(有/没有带有 phpmyadmin 的 podman 容器)

什么是 SQLite?全面概述 什么是 SQLite?全面概述 Mar 04, 2025 pm 03:55 PM

什么是 SQLite?全面概述

在MacOS上运行多个MySQL版本:逐步指南 在MacOS上运行多个MySQL版本:逐步指南 Mar 04, 2025 pm 03:49 PM

在MacOS上运行多个MySQL版本:逐步指南

哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么? 哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么? Mar 21, 2025 pm 06:28 PM

哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么?

如何为MySQL连接配置SSL/TLS加密? 如何为MySQL连接配置SSL/TLS加密? Mar 18, 2025 pm 12:01 PM

如何为MySQL连接配置SSL/TLS加密?

See all articles