专栏首页golang+php一条sql语句究竟是如何执行的

一条sql语句究竟是如何执行的

点击上方蓝字关注我们

相信做后端的同学肯定离不开一个话题,就是 mysql,大家也花式的执行过各种各样的 sql 语句,然后得到返回结果,那么一条 sql 语句执行究竟经历了哪些步骤呢?今天让我们来一探究竟。

我们先来看一看 mysql 的整体的架构图

其实从上图可以看出,由客户端发出请求之后,mysql主要分为server层和存储引擎层

server层

连接器

连接器主要是与客户端建立连接, 包含本地socket和大多数基于客户端/服务端工具实现的类似于tcp/ip的通信。连接成功之后会同时校验用户的权限,等相关安全方案。如我们常用的建立连接方式

mysql -h ip -P 3306 -u root -p

只要用过数据库的同学,相信对上面的连接方式并不陌生,在连接之后还有一些权限验证等等,这些都是在连接器中完成的。

这里需要注意的一点就是,在线上的应用中,会采用数据库连接池的方式,来避免频繁的开关连接。

另外可以用show processlist; 用来显示用户正在运行的线程。

分析器

对客户端传来的 sql 进行分析,这将包括预处理与解析过程,并进行关键词的提取、解析,并组成一个解析树。具体的解析词包括但不局限于 select/update/delete/or/in/where/group by/having/count/limit 等,如果分析到语法错误,会直接抛给客户端异常:

  ERROR:You have an error in your SQL syntax.

比如:

select * from user where userId =1234;

在分析器中就通过语义规则器将select from where这些关键词提取和匹配出来,mysql会自动判断关键词和非关键词,将用户的匹配字段和自定义语句识别出来。这个阶段也会做一些校验:比如校验当前数据库是否存在user表,同时假如User表中不存在userId这个字段同样会报错:

unknown column in field list

优化器

进入优化器说明sql语句是符合标准语义规则并且可以执行。优化器会根据执行计划选择最优的选择,匹配合适的索引,选择最佳的方案。比如一个典型的例子是这样的:

表T,对A、B、C列建立联合索引(A,B,C),在进行查询的时候,当sql查询条件是:select xx where B=x and A=x and C=x.很多人会以为是用不到索引的,但其实会用到,虽然索引必须符合最左原则才能使用,但是本质上,优化器会自动将这条sql优化为:where A=x and B=x and C=X,这种优化会为了底层能够匹配到索引,同时在这个阶段是自动按照执行计划进行预处理,mysql会计算各个执行方法的最佳时间,最终确定一条执行的sql交给最后的执行器

执行器

执行器会调用对应的存储引擎执行 sql。主流的是MyISAM 和 Innodb。

缓存

数据库在8.0以前是有缓存的,但是说实话这个用处不大,一般线上也不会开启数据库缓存,首先因为开启缓存也是占一定的开销的,另外实际应用中一模一样的sql语句重复多次查询的场景很少很少,所以在8.0以后直接把缓存给去掉了,所以缓存这里咱们就不讨论了。

总结

MySQL server层逻辑架构从上往下可以分为三层:

(1)第一层:处理客户端连接、授权认证等。

(2)第二层:服务器层,负责查询语句的解析、优化、缓存以及内置函数的实现、存储过程等。

(3)第三层:存储引擎,负责MySQL中数据的存储和提取。MySQL中服务器层不管理事务,事务是由存储引擎实现的。MySQL支持事务的存储引擎有InnoDB、NDB Cluster等,其中InnoDB的使用最为广泛;其他存储引擎不支持事务,如MyIsam、Memory等。具体过程都在图中有所标注,篇幅有限,大家可以先有个大概的认识,具体的步骤咱们后面继续更新。

本文分享自微信公众号 - 程序员养成日记(programmer_grow),作者:饭米粒

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-12-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Memcache CAS协议介绍及使用

    所谓CAS,check and set,在写操作时,先检查是否被别的线程修改过。 基本原理非常简单,一言以蔽之,就是“版本号”。每个存储的数据对象,多有一个版...

    程序员养成日记
  • Memcache的内存管理和删除机制

    如果c语言直接向系统malloc,free申请和释放内存时,在不断的申请和释放的过程中,形成了一些很小的内存片段,无法再利用,这种空闲,但无法利用内存的现象,-...

    程序员养成日记
  • redis源码之set结构

    关于set的命令和常用场景我们暂时先不说了,如果对命令不太熟悉的朋友可以用 help @set命令查看,我们先来看set中的一种现象

    程序员养成日记
  • SwiftUI:创建底部导航栏 tabBar

    导航视图非常适合让我们创建分层的视图堆栈,以使用户能够向下获取数据,但对于显示不相关的数据而言效果不佳。为此,我们需要使用SwiftUI的 TabView,它会...

    韦弦zhy
  • R Tricks: 如何巧为观测标记序号

    本期大猫课堂将会开始一个新的系列:你不知道的R Tricks。这个系列将搬运stackoverflow.com(以后简称SO)上关于R数据处理的一些经典问答。大...

    用户7652506
  • linux下mysql忘记密码

    今天在服务器安装mysql之后,登录发现密码错误,但是我没有设置密码呀,最后百度之后得知,mysql在5.7版本之后会自动创建一个初始密码。 报错如下:

    kirin
  • 5.3CentOS@安装mysql8.0教程

    (2).输入:mysql> SHOW VARIABLES LIKE 'validate_password.%';

    itjim
  • 设置mysql用户密码(5.6/5.7)、远程连接数据库、常用命令

    首次直接使用mysql会提示‘该命令不存在’,原因是还没有将该命令加入环境变量,如果要使用该命令,需要使用其绝对路径:/usr/local/mysql/bin/...

    阿dai学长
  • ELK总结——第四篇Kibana的简介

    Kibana 是为 Elasticsearch设计的开源分析和可视化平台。你可以使用 Kibana 来搜索,查看存储在 Elasticsearch 索引中的数据...

    胡齐
  • Windows下MySQL 8.x和8.x以前版本的安装步骤

    官方下载地址:https://dev.mysql.com/downloads/mysql/

    魏晓蕾

扫码关注云+社区

领取腾讯云代金券