搜索
首页数据库mysql教程mysql学习之select查询语句到底是怎么执行的?

本篇文章给大家带来了关于mysql中select语句执行的相关知识,其中包括了连接器、分析器、优化器和执行器,希望对大家有帮助。

mysql学习之select查询语句到底是怎么执行的?

mysql 作为一个关系型数据库,在国内使用应该是最广泛的。也许你司使用 Oracle、Pg 等等,但是大多数互联网公司,比如我司使用得最多的还是 Mysql,重要性不言而喻。

执行select * from table,数据库底层到底发生了啥?从而我们得到数据呢?

假设现在我有张 user 表,只有两列,一列 id 自增的,一列 name 是  varchar 类型。建表语句是这样的:

CREATE TABLE IF NOT EXISTS `user`(
   `id` INT UNSIGNED AUTO_INCREMENT,
   `name` VARCHAR(100) NOT NULL,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

问题就是下面这个语句的执行过程。

select * from user where id = 1;

01 mysql 架构概览

要想理解这个问题就必须要知道 mysql 的内部架构。为此,我画了张 mysql 的架构图(你也可以理解为 sql 查询语句的执行过程),如下所示:

36.png

首先 msql 分为 server 层和存储引擎层两个部分。server 层包括四个功能模块,分别是:连接器、查询缓存、优化器、执行器。这一层负责了 mysql 的所有核心工作,比如:内置函数、存储过程、触发器以及视图等。

而存储引擎层则是负责数据的存取。注意,存储引擎在 mysql 是可选的,常见的还有:InnoDB、MyISAM 以及 Memory等,最常用的就是 InnoDB。现在默认的存储引擎也是它(从 mysql 5.5.5 版本开始),大家可以看到我上面的建表语句就是指定了 InnoDB 引擎。当然,你不指定的话默认也是它。

由于存储引擎是可选的,所以 mysql 中,所有的存储引擎其实是共用一个 server层的。回到正题,我们就以这张图的流程来解决一下小胖的问题。

1.1 连接器

首先,数据库要执行 sql,肯定要先连接数据库吧。这部分工作就是由连接器完成。它负责校验账户密码、获取权限、管理连接数,最终与客户端建立连接等工作。mysql 链接数据库是这样写的:

mysql -h 127.0.0.1 -P 3306 -u root -p
# 127.0.0.1 : ip 3306 : 端口 root : 用户名

运行命令之后需要输入密码,当然也可以跟在 -p 后面。不过不建议这么做,会有密码泄露的风险。

输入命令后,连接器根据你的账户名密码验证身份。这是会出现两种情况:

  • 账号或密码不对,服务端会返回一个 "ERROR 1045 (28000): Access denied for user 'root'@'127.0.0.1' (using password: YES)" 的错误,退出连接。

  • 验证通过,连接器就会到权限表查出你的权限。之后你有啥权限都要通过这时读到的权限进行判断。

注意,我说的是此时查到的权限。就算你用管理员账号修改了当前用户的权限,此时已连接上的当前用户不受影响,必须要重启 mysql 新的权限才会生效。

1.1.1 查看连接状态

连接完成,如果后续没有做任何事情,这个连接就处于空闲状态。你可以用 show processlist; 命令查看 mysql 的连接信息,如下图,我的数据库连接都是 Sleep 状态的,除了执行 show processlist 操作的连接。

01.png

1.1.2 控制连接

如果客户端太长时间没有操作,此连接将会自动断开。这个时间默认是 8 小时,由参数 wait_timeout 控制。如果断开以后继续操作就会收到 "Lost connection to MySQL server during query"的错误。这时就必须重连才能执行请求。

数据库里面有长短连接之分,长连接:连接成功后不断有请求,就会一直使用同一连接。短连接:每次执行完几次请求就断开连接,下次需要再建立。

由于建立连接是比较耗时的操作,所以建议使用长连接。但这会有个问题长连接一直连着就会导致内存占用过大,被系统强行沙雕。从而导致 MySQL 异常重启。如何解决呢?两个方法:

  • 定期断开长连接。使用特定时间,或者程序判断执行一个占用内存大的操作后,断开连接。之后需要操作就重连。

  • mySQL 5.7 或以上版本,可以在每次执行一个占用内存大的操作后,执行mysql_reset_connection来重新连接资源,此时不需重连或重新做权限认证,但会把连接状态恢复到刚创建完时。

1.2 查询缓存

连接建立以后可以执行 select 语句了。这就会来到第二步:查询缓存。

查询缓存中存储的数据是 key-value 的形式,key 是查询语句,value 是查询的结果。逻辑是这样的:先看看查询缓存有没该语句对应的 value?有则直接取出返回客户端,无则继续到数据库执行语句。查出结果后会放一份到缓存中,再返回客户端。

你可能发现缓存真的香,但是并不建议使用查询缓存,因为有弊端。查询缓存的失效非常频繁,只有某个表有更新。它马上失效了,对于经常更新的表来说,命中缓存的概率极低。它仅仅适用于那些不经常更新的表。

而 MySQL 似乎也考虑到这点了。提供了 query_cache_type 参数,把它设置为 DEMAND 就不再适用韩村。而对于要使用缓存的语句则可用 SQL_CACHE 显示指定,像这样:

select SQL_CACHE * from user where id = 1;

PS:MySQL 8.0 及以上版本把查询缓存删掉了,之后再也没有这块功能了。

1.3 分析器

如果没有命中缓存就进入分析器,这里就是对 sql 进行分析。分析器会做词法分析。你输入的 sql 是啥,由啥组成,MySQL 都需要知道它们代表什么。

首先根据 "select" 识别出这是查询语句。字符串"user"识别成"表名 user"、字符串"id"识别成"列名id"。

之后进行语法分析,它会根据输入的语句分析是不是符合 MySQL 的语法。具体表现就是 select、where、from 等关键字少了个字母,明显不符合 MySQL 语法,这次就会报个语法错误的异常:它一般会提示错误行数,关注"use near"后面即可。

02.png

1.4 优化器

过了分析器,就来到了优化器。MySQL 是个聪明的仔,再执行之前会自己优化下客户端传过来的语句,看看那种执行起来不那么占内存、快一点。比如下面的 sql 语句:

select * from user u inner join role r on u.id = r.user_id where u.name = "狗哥" and r.id = 666

它可以先从 user 表拿出 name = "狗哥" 记录的 ID 值再跟 role 表内连接查询,再判断 role 表里面 id 的值是否 = 666

也可以反过来:先从 role 表拿出 id = 666 记录的 ID 值再跟 user 表内连接查询,在判断 user 表里面的 name 值是否 = "狗哥"。

两种方案的执行结果是一样的,但是效率不一样、占用的资源也就不一样。优化器就是在选择执行的方案。它优化的是索引应该用哪个?多表联查应该先查哪个表?怎么连接等等。

1.5 执行器

分析器知道了做啥、优化器知道了应该怎么做。接下来就交给执行器去执行了。

开始执行,判断是否有相应的权限。比如该账户对 user 表没权限就返回无权限的错误,如下所示:

select * from user where id = 1;
ERROR 1142 (42000): SELECT command denied to user 'nasus'@'localhost' for table 'user'

PS:如果命中缓存没走到执行器这里,那么在返回查询结果时做权限验证。

回到正题,如果有权限,继续打开表执行。执行器会根据表定义的引擎去使用对应接口。比如我们上面的 sql 语句执行流程是这样的:

  • 走 id 索引、调用 InnoDB 引擎取"满足条件的第一行"接口,再循环调用"满足条件的下一行"接口(这些接口都是存储引擎定义好的),直到表中不再有满足条件的行。执行器就将上述遍历得到的行组成结果集返回给客户端。

  • 对于 id 不是索引的表,执行器只能调用"取表记录的第一行"接口,再判断 id 是否 = 1。如果不是则跳过,是则存在结果集中;再调存储引擎接口取"下一行",重复判断逻辑,直到表的最后一行。

至此,整个 SQL 的执行流程完毕,

推荐学习:mysql视频教程

以上是mysql学习之select查询语句到底是怎么执行的?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:掘金。如有侵权,请联系admin@php.cn删除
您可以使用哪些工具来监视MySQL性能?您可以使用哪些工具来监视MySQL性能?Apr 23, 2025 am 12:21 AM

如何有效监控MySQL性能?使用mysqladmin、SHOWGLOBALSTATUS、PerconaMonitoringandManagement(PMM)和MySQLEnterpriseMonitor等工具。1.使用mysqladmin查看连接数。2.用SHOWGLOBALSTATUS查看查询数。3.PMM提供详细性能数据和图形化界面。4.MySQLEnterpriseMonitor提供丰富的监控功能和报警机制。

MySQL与SQL Server有何不同?MySQL与SQL Server有何不同?Apr 23, 2025 am 12:20 AM

MySQL和SQLServer的区别在于:1)MySQL是开源的,适用于Web和嵌入式系统,2)SQLServer是微软的商业产品,适用于企业级应用。两者在存储引擎、性能优化和应用场景上有显着差异,选择时需考虑项目规模和未来扩展性。

在哪些情况下,您可以选择SQL Server而不是MySQL?在哪些情况下,您可以选择SQL Server而不是MySQL?Apr 23, 2025 am 12:20 AM

在需要高可用性、高级安全性和良好集成性的企业级应用场景下,应选择SQLServer而不是MySQL。1)SQLServer提供企业级功能,如高可用性和高级安全性。2)它与微软生态系统如VisualStudio和PowerBI紧密集成。3)SQLServer在性能优化方面表现出色,支持内存优化表和列存储索引。

MySQL如何处理角色集和碰撞?MySQL如何处理角色集和碰撞?Apr 23, 2025 am 12:19 AM

mySqlManagesCharacterSetsetSandCollat​​ionsyutusututf-8asthEdeFault,允许ConfigurationAtdataBase,table和columnlevels,AndrequiringCarefullageLignmentToavoidMismatches.1)setDefeaultCharactersetTercharactersetEtCollacterSeteTandColletationForAdataBase.2)conformentcollecharactersettersetertersetcollat​​ertersetcollat​​ioncollat​​ion

MySQL中有什么触发器?MySQL中有什么触发器?Apr 23, 2025 am 12:11 AM

MySQL触发器是与表相关联的自动执行的存储过程,用于在特定数据操作时执行一系列操作。1)触发器定义与作用:用于数据校验、日志记录等。2)工作原理:分为BEFORE和AFTER,支持行级触发。3)使用示例:可用于记录薪资变更或更新库存。4)调试技巧:使用SHOWTRIGGERS和SHOWCREATETRIGGER命令。5)性能优化:避免复杂操作,使用索引,管理事务。

您如何在MySQL中创建和管理用户帐户?您如何在MySQL中创建和管理用户帐户?Apr 22, 2025 pm 06:05 PM

在MySQL中创建和管理用户账户的步骤如下:1.创建用户:使用CREATEUSER'newuser'@'localhost'IDENTIFIEDBY'password';2.分配权限:使用GRANTSELECT,INSERT,UPDATEONmydatabase.TO'newuser'@'localhost';3.修正权限错误:使用REVOKEALLPRIVILEGESONmydatabase.FROM'newuser'@'localhost';然后重新分配权限;4.优化权限:使用SHOWGRA

MySQL与Oracle有何不同?MySQL与Oracle有何不同?Apr 22, 2025 pm 05:57 PM

MySQL适合快速开发和中小型应用,Oracle适合大型企业和高可用性需求。1)MySQL开源、易用,适用于Web应用和中小型企业。2)Oracle功能强大,适合大型企业和政府机构。3)MySQL支持多种存储引擎,Oracle提供丰富的企业级功能。

与其他关系数据库相比,使用MySQL的缺点是什么?与其他关系数据库相比,使用MySQL的缺点是什么?Apr 22, 2025 pm 05:49 PM

MySQL相比其他关系型数据库的劣势包括:1.性能问题:在处理大规模数据时可能遇到瓶颈,PostgreSQL在复杂查询和大数据处理上表现更优。2.扩展性:水平扩展能力不如GoogleSpanner和AmazonAurora。3.功能限制:在高级功能上不如PostgreSQL和Oracle,某些功能需要更多自定义代码和维护。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

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

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)