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
目录
相关文章
|
1月前
|
SQL 运维 关系型数据库
MySQL 运维 SQL 备忘
MySQL 运维 SQL 备忘录
46 1
|
21天前
|
SQL 关系型数据库 MySQL
MySql5.6版本开启慢SQL功能-本次采用永久生效方式
MySql5.6版本开启慢SQL功能-本次采用永久生效方式
33 0
|
21天前
|
SQL 关系型数据库 MySQL
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
31 0
|
1月前
|
SQL 存储 关系型数据库
mysql 数据库空间统计sql
mysql 数据库空间统计sql
45 0
|
1月前
|
SQL 存储 关系型数据库
mysql SQL必知语法
本文详细介绍了MySQLSQL的基本语法,包括SELECT、FROM、WHERE、GROUPBY、HAVING、ORDERBY等关键字的使用,以及数据库操作如创建、删除表,数据类型,插入、查询、过滤、排序、连接和汇总数据的方法。通过学习这些内容,读者将能更好地管理和操
14 0
|
10天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
25 1
|
12天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
28 4
|
1月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
61 3
Mysql(4)—数据库索引
|
19天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
87 1
|
21天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
61 2