MySQL的SQL执行背后隐藏了什么

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL的SQL执行背后隐藏了什么

MySQL的基本体系和架构介绍


相信在大部分的程序员在工作中都有接触过MySQL这款数据库,在MySQL的官网上边,你会看到这样的一段介绍内容:


网络异常,图片无法展示
|


大致翻译过来的意思就是说:


MySQL是世界上最受欢迎的开源数据库。无论您是快速增长的Web资产,技术ISV还是大型企业,MySQL都能经济高效地帮助您交付高性能,可扩展的数据库应用程序。


这款开源的数据库,其源码在github上边的地址为:github.com/mysql/mysql… star还是挺多的。


那么既然是一款公认好用的开源数据库,我们是否应该对它进行一个深入的了解呢?

下边我画了一个大致的MySQL基本架构图:


网络异常,图片无法展示
|


客户端


MySQL的整体结构可以分成2个大模块,分别是客户端和服务端。这里头说的客户端是指提供连接MySQL的工具集合,常见的客户端工具有mysql client,mysqladmin,mysqldump,mysqlcheck,mysqlimport,mysqlshow等等。MySQL数据库本身提供的连接方式包含有多种,其中最常见的就是基于TCP/IP协议进行连接了。基础的命令内容为:


mysql -h [地址] -u [用户名] -p [密码]
复制代码


在安装完毕了MySQL数据库之后,我们会发现数据库自身已经帮我们预先设置了一个名字叫做mysql的数据库,每次获取链接的时候就会到该库里面的User表检索账号信息以及相关的权限。


在Linux系统中,有很多进程间通信方式,套接字(Socket)就是其中的一种。但传统的套接字的用法都是基于TCP/IP协议栈的,需要指定IP地址。如果不同主机上的两个进程进行通信,当然这样做没什么问题。但是,如果只需要在一台机器上的两个不同进程间通信,还要用到IP地址就有点大材小用了。


MySQL数据库自身是支持UNIX域套接字进行通信的,因此在MySQL的文件目录下边会有这么一份文件:mysql.sock。


这份文件主要是通过Unix域套接字供我们将本地连接数据库服务器使用。


以前笔者就遇到过sock文件被修改,导致连接数据库异常的情况,例如mysql的log中出现这种报错记录:


Could not create unix socket lock file
复制代码


如果sock文件丢失的话,可以重新创建一份sock文件进行通信。


MySQL的链接分析


关于mysql的链接部分,可以先思考一下下边的这几个问题:


MySQL的链接分类包含有哪些?


其实MySQL的链接包含有很多种类型,常见的类型有:


Unix Sockets

TCP/IP

TLE/SSL


在MySQL的链接中,主要的分类有长链接类型和短连接类型。


短连接


每次客户端和服务端进行通信的时候,都需要创建链接—》进行通信—》关闭连接。这种链接的我们将其定义为短连接,从它的操作来看这种连接的行为对于资源的浪费和网络的消耗是最高的。所以通常我们在工作中较少使用。


长链接


长链接是我们工作中比较常用的类型,客户端第一次构建连接之后就不会轻易断开,这样可以给后边多次连接的程序应用所使用,这种设计的好处在于能够减少资源的损耗,相对于短连接来说要高效些。长链接通常都会被设计存储在连接池里面,从而减少连接创建的开销。如果在工作中遇到了一些并发请求比较高的业务场景,光是单单通过配置连接池的方式还是不够的,还需要有经验的开发人员在业务层进行相应的隔离。


对于一些访问量比较低的应用其实可以不使用到连接池这种较重的组件,有可能大量的长链接建立了之后都处于sleep状态,这样对于内存资源的占用会比较高。


服务端


每次客户端想要链接到服务端都需要从服务端的连接池获取相应的连接。假设我们每次连接都需要完成 构建链接,当我们获取到了链接之后,在mysql的server端可以通过这样一个命令来对每个链接的状态进行查看:


mysql> show processList;
+----+-------------+-----------+------+---------+--------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time   | State                                                  | Info             |
+----+-------------+-----------+------+---------+--------+--------------------------------------------------------+------------------+
|  2 | system user |           | NULL | Connect | 195290 | Waiting for master to send event                       | NULL             |
|  3 | system user |           | NULL | Connect |    257 | Slave has read all relay log; waiting for more updates | NULL             |
| 19 | root        | localhost | NULL | Query   |      0 | starting                                               | show processList |
+----+-------------+-----------+------+---------+--------+--------------------------------------------------------+------------------+
3 rows in set (0.01 sec)
复制代码


除了上边的这种情况之外,如果当连接数较多的时候,希望能够清晰查看到连接的信息可以通过下边这条指令来操作:


show status like 'Threads%';
结果内容:
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 213   |  当前被缓存的空闲线程的数量
| Threads_connected | 191    | 正在使用(处于连接状态)的线程
| Threads_created   | 409   |  服务启动以来,创建了多少个线程
| Threads_running   | 5     |  正在忙的线程(正在查询数据,传输数据等等操作)
+-------------------+-------+
复制代码


查询缓存


对于一些数据修改变动比较少的表,MySQL内部提供了一套叫做Query Cache的缓存池来进行存储。MySQL可以通过以下命令来查看内部的查询缓存参数值:


mysql> show variables like '%query_cache%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| have_query_cache             | YES     |
| query_cache_limit            | 1048576 |
| query_cache_min_res_unit     | 4096    |
| query_cache_size             | 1048576 |
| query_cache_type             | OFF     |
| query_cache_wlock_invalidate | OFF     |
+------------------------------+---------+
6 rows in set (0.00 sec)
复制代码


关于查询缓存的功能,在MySQL中是根据sql语句来做缓存检索的,默认情况下该缓存属性是关闭的,对于更新频率较高的表而言,设置查询缓存其实本身的命中率并不高,因此该功能MySQL也并不提倡使用,在MySQL8.0的时候该功能也被移除了。MySQL服务器团队有一篇关于此的详细文章有所提及到移除的原因,具体地址如下:


mysqlserverteam.com/mysql-8-0-r…


语法分析器


接下来便是语法分析环节了,该模块主要是对传入的SQL语句内容做一些语法内容的校验,例如判断该语句是属于DQL还是DML等类型。其实我个人觉得MySQL里面最为复杂的部分就是SQL的语法树生产的部分,对于这部分的生成需要对编译器的原理有一定的了解,我个人的功力不是很足,所以这里借用了美团一朋友之前分享给我的图片来大概演示:


网络异常,图片无法展示
|


优化器

有时候你会发现,执行的一条SQL可能并不会按照预期的方式来走索引,这是因为MySQL内部有优化器这么一个角色的存在。当然索引的选择只是优化器的其中一项特点,优化器的目的就是通过一定的逻辑判断,将sql执行的效率发挥到最高效化。


执行器

当Sql准备好了,优化结束了,执行器便会发起sql请求引擎层的接口,这个环节中,执行器还回去判断当前请求的会话是否有权限执行相关的SQL语句。


存储引擎

可以说整个数据库的核心部分就是存储引擎环节了,不同的存储引擎对数据的存储结构和算法设计方便都有着巨大的差别,而且不同的存储引擎专门为不同的应用场景所设计。目前我们主流的存储引擎有Innodb,MyISAM,Memory,等


通过下边的这条命令我们可以看到MySQL数据库所支持的存储引擎有哪些:


mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
复制代码


关于MySQL的整体架构介绍大概到这里就先暂时告一段落了,下一篇文章我会讲解一些关于存储引擎的比对问题。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4天前
|
SQL 运维 关系型数据库
MySQL 运维 SQL 备忘
MySQL 运维 SQL 备忘录
20 1
|
14天前
|
SQL 存储 关系型数据库
SQL文件导入MySQL数据库的详细指南
数据库中的数据转移是一项常规任务,无论是在数据迁移过程中,还是在数据备份、还原场景中,导入导出SQL文件显得尤为重要。特别是在使用MySQL数据库时,如何将SQL文件导入数据库是一项基本技能。本文将详细介绍如何将SQL文件导入MySQL数据库,并提供一个清晰、完整的步骤指南。这篇文章的内容字数大约在
32 1
|
6天前
|
SQL 存储 关系型数据库
mysql 数据库空间统计sql
mysql 数据库空间统计sql
19 0
|
6天前
|
SQL 存储 关系型数据库
mysql SQL必知语法
本文详细介绍了MySQLSQL的基本语法,包括SELECT、FROM、WHERE、GROUPBY、HAVING、ORDERBY等关键字的使用,以及数据库操作如创建、删除表,数据类型,插入、查询、过滤、排序、连接和汇总数据的方法。通过学习这些内容,读者将能更好地管理和操
8 0
|
14天前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
54 0
|
10天前
|
存储 SQL 关系型数据库
Mysql学习笔记(二):数据库命令行代码总结
这篇文章是关于MySQL数据库命令行操作的总结,包括登录、退出、查看时间与版本、数据库和数据表的基本操作(如创建、删除、查看)、数据的增删改查等。它还涉及了如何通过SQL语句进行条件查询、模糊查询、范围查询和限制查询,以及如何进行表结构的修改。这些内容对于初学者来说非常实用,是学习MySQL数据库管理的基础。
44 6
|
7天前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
40 3
Mysql(4)—数据库索引
|
10天前
|
SQL Ubuntu 关系型数据库
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
本文为MySQL学习笔记,介绍了数据库的基本概念,包括行、列、主键等,并解释了C/S和B/S架构以及SQL语言的分类。接着,指导如何在Windows和Ubuntu系统上安装MySQL,并提供了启动、停止和重启服务的命令。文章还涵盖了Navicat的使用,包括安装、登录和新建表格等步骤。最后,介绍了MySQL中的数据类型和字段约束,如主键、外键、非空和唯一等。
30 3
Mysql学习笔记(一):数据库详细介绍以及Navicat简单使用
|
14天前
|
缓存 算法 关系型数据库
Mysql(3)—数据库相关概念及工作原理
数据库是一个以某种有组织的方式存储的数据集合。它通常包括一个或多个不同的主题领域或用途的数据表。
41 5
Mysql(3)—数据库相关概念及工作原理
|
1天前
|
存储 关系型数据库 MySQL
如何在MySQL中创建数据库?
【10月更文挑战第16天】如何在MySQL中创建数据库?