第三篇:SQL是如何执行的?

本文详细介绍了MySQL的架构,包括server层和存储引擎层,重点讲解了一条SQL从连接、分析、优化到执行的过程。连接器负责建立连接并验证权限,查询缓存(MySQL8已删除)存储查询结果,分析器检查SQL语法,优化器选择最佳执行计划,执行器执行SQL并校验权限。以DROPTABLE和CREATE TABLE语句为例,解释了索引使用和查询优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MySQL整体架构图

  MySQL架构分为server层与存储引擎层,server层是MySQL最核心的一部分,它包含连接器,存储引擎(8之前),分析器,优化器,执行器。存储引擎是用于存取数据的,是可插拔的,目前主流的存储引擎是Innodb。
image.png
以下方SQL为例来叙述一条SQL是如何执行的:

DROP TABLE IF EXISTS `user_phone`;
CREATE TABLE `user_phone` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `phone_id` int(11) NOT NULL,
  `info` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_user_phone_id` (`user_id`,`phone_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SELECT user_id,phone_id from user_phone WHERE phone_id = '33333' and user_id = '33333';

连接器

  连机器是MySQL的门户,负责与客户端建立连接,要操作MySQL中的数据的前提是你能够连接上MySQL。常见的连接方式,通过JDBC连接,连接所需的四个参数是url,driver类路径,username,password,从这四个参数可以看出,连接器是通过账号密码来登录的。

连接器除了上述建立连接的功能外,还有其他功能,如用户权限校验,维持客户端与MySQL的连接(一个连接超过指定时间会自动断开,由参数wait_timeout 控制,默认是8小时)

show global variables like "wait_timeout";
set global wait_timeout=28800; 设置全局服务器关闭非交互连接之前等待活动的秒数

查询缓存

  查询缓存在MySQL8中已经被删除了,原因是比较鸡肋。MySQL执行一条SQL语句的大致过程分两步

  1. 第一步先看查询缓存有没有对应的记录,如果没有执行第二步
  2. 查询数据库获取结果集,并写入查询缓存

  鸡肋的地方在于每当对应表有写操作时就会清空该表的所有缓存,在大部分场景下表都是有写入操作的,也就是说缓存被清空是常有的事。我的理解是MySQL删除第一步操作可以直接省下去查询缓存的这部分时间。

  查询缓存也并不是一无是处,它可以被用在静态表,也就是不会有写操作的表,比如全国省市区表。查询缓存是可控的,可以在配置文件中修改

my.cnf

#query_cache_type有3个值 0代表关闭查询缓存OFF,1代表开启ON,2(DEMAND)代表当sql语句中有SQL_CACHE关键词时才缓存

query_cache_type=2

理解好像不太对,更新缓存可能是因为怕读写不一致

比如,对于update t_user set age=18 where name=‘bravo’ 和 update t_user set age=20 where height=180,你能保证这两条操作的是完全不同的数据吗?为了校验当前SQL是否会影响已缓存的数据,你必须将本次查询的结果和缓存数据进行对比,然后确定是否要更新缓存…然而,你都查出结果了,直接返回岂不是更快?

分析器

  分析器主要是分析SQL是否符合MySQL规则,简单理解就是,这条SQL是否可以在MySQL中执行。平时我们看到的语法错误,大部分来自于分析器。比如上述SQL中,where 写成 wher 就会出现以下错误:
image.png

优化器

  优化器的作用就是根据MySQL的规则让你的SQL执行效率跟高,本例中建立的联合索引是(user_id,phone_id),查询条件是phone_id = ? and user_id = ?,根据最左前缀原理,这条SQL是不会走索引的。我们通过Explain来看下是否走了索引。
image.png
从图中可以看出,该SQL走了索引,那么该SQL被优化过也可以证明了。

执行器

引用MySQL实战45讲

分析器经过一顿分析,已经选定要使用的索引,接下来开始真正执行SQL。大致分为3步:

  • 权限校验(连接器阶段已经读取权限,这里只要校验当前用户是否拥有操作这张表的权限)
  • 选择引擎
  • 调用引擎提供的接口

比如对于下面这条SQL:

mysql> select SQL_CACHE * from T where ID=10

执行器的执行流程是这样的:

  • 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中
  • 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行
  • 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端

至此,这个语句就执行完成了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI极客Jayden 

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值