【MySQL】逻辑架构与存储引擎

一、逻辑架构

1、MySQL逻辑架构

在这里插入图片描述
我们可以根据上图来对sql的执行过程进行分析

  • 第一步:客户端与服务器建立一个连接,从连接池中分配一个线程处理SQL语句
  • 第二步:SQL接口接受SQL指令
  • 第三步:如果是5.7版本,就会先去缓存中检查是否已经有查询结果存在,如果存在就返回此结果给客户端。如果是8.0版本,就会使用解析器,将SQL语句解析成语法树,如果SQL语法有问题,就会在此报错
  • 第四步:SQL会使用优化器生成执行计划,例如决定索引的使用,表之间的连接顺序等
  • 第五步:调用存储引擎,去内存中查询数据(由文件系统加载到内存中)
  • 第六步:查询到结果后,如果是5.7版本,会将结果写到缓存中,再走到SQL接口,释放占用的工作线程,将结果返回给客户端(如果是8.0,就跳过写入缓存的步骤)

2、MySQL服务架构

  • 第一层:连接层
    • 对客户端的请求进行身份认证
    • 从权限表中查询当前客户端的权限信息
    • 提供控制客户端连接数量的连接池以及处理SQL请求的线程池
  • 第二层:服务层,包括上面介绍的SQL接口、解析器、优化器和缓存
  • 第三层:引擎层,真正的负责了MySQL中数据的存储和提取,对物理服务器维护的底层数据进行操作

3、查看SQL执行耗时

mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
|           0 |
+-------------+
1 row in set, 1 warning (0.00 sec)mysql>
mysql>
mysql>
mysql> SET @@session.profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)mysql>

首先,我们要打开profiling这个变量。便于我们查看SQL执行的耗时
show profiles:查看所有的查询语句的信息
show profile;:查看最近一次查询语句的执行耗时
show profile for query id编号:查看指定id的查询语句执行耗时

  • MySQL8.0,可以发现同样的查询语句执行流程是一样的
mysql> select * from test1;
+------+--------+
| id   | name   |
+------+--------+
|    2 | 十年   |
+------+--------+
1 row in set (0.01 sec)mysql>
mysql> select * from test1;
+------+--------+
| id   | name   |
+------+--------+
|    2 | 十年   |
+------+--------+
1 row in set (0.00 sec)mysql>
mysql> show profiles;
+----------+------------+---------------------+
| Query_ID | Duration   | Query               |
+----------+------------+---------------------+
|        1 | 0.00018475 | select @@profiling  |
|        2 | 0.00150575 | SELECT DATABASE()   |
|        3 | 0.00339475 | show databases      |
|        4 | 0.00165200 | show tables         |
|        5 | 0.00973450 | select * from test1 |
|        6 | 0.00024725 | select * from test1 |
+----------+------------+---------------------+
6 rows in set, 1 warning (0.00 sec)mysql>
mysql> show profile;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000108 |
| Executing hook on transaction  | 0.000003 |
| starting                       | 0.000006 |
| checking permissions           | 0.000005 |
| Opening tables                 | 0.000027 |
| init                           | 0.000004 |
| System lock                    | 0.000006 |
| optimizing                     | 0.000003 |
| statistics                     | 0.000009 |
| preparing                      | 0.000014 |
| executing                      | 0.000033 |
| end                            | 0.000002 |
| query end                      | 0.000003 |
| waiting for handler commit     | 0.000007 |
| closing tables                 | 0.000006 |
| freeing items                  | 0.000007 |
| cleaning up                    | 0.000006 |
+--------------------------------+----------+
17 rows in set, 1 warning (0.01 sec)mysql>
mysql> show profile for query 5;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000075 |
| Executing hook on transaction  | 0.000005 |
| starting                       | 0.000009 |
| checking permissions           | 0.000007 |
| Opening tables                 | 0.000037 |
| init                           | 0.000006 |
| System lock                    | 0.000010 |
| optimizing                     | 0.000007 |
| statistics                     | 0.000014 |
| preparing                      | 0.000018 |
| executing                      | 0.009485 |
| end                            | 0.000014 |
| query end                      | 0.000004 |
| waiting for handler commit     | 0.000010 |
| closing tables                 | 0.000010 |
| freeing items                  | 0.000016 |
| cleaning up                    | 0.000009 |
+--------------------------------+----------+
17 rows in set, 1 warning (0.00 sec)mysql>
mysql> show profile for query 6;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000108 |
| Executing hook on transaction  | 0.000003 |
| starting                       | 0.000006 |
| checking permissions           | 0.000005 |
| Opening tables                 | 0.000027 |
| init                           | 0.000004 |
| System lock                    | 0.000006 |
| optimizing                     | 0.000003 |
| statistics                     | 0.000009 |
| preparing                      | 0.000014 |
| executing                      | 0.000033 |
| end                            | 0.000002 |
| query end                      | 0.000003 |
| waiting for handler commit     | 0.000007 |
| closing tables                 | 0.000006 |
| freeing items                  | 0.000007 |
| cleaning up                    | 0.000006 |
+--------------------------------+----------+
17 rows in set, 1 warning (0.00 sec)mysql>
  • MySQL5.7

因为这个版本存在缓存,所以我们开启一下看看同样的SQL,两次执行会有什么区别
我们需要打开缓存配置,将其设置为query_cache_type=2,按需开启,重启MySQL服务

[root@myLinux1 ~]# vim /etc/my.cnf
[root@myLinux1 ~]# systemctl restart mysqld
[root@myLinux1 ~]#

重复执行2次使用缓存的查询,可以看出,使用缓存的情况下,如果SQL语句一样并且缓存中已有结果,就不会继续往下执行了

mysql> select SQL_CACHE * from test1 WHERE id = 1;
+------+--------+
| id   | name   |
+------+--------+
|    1 | decade |
+------+--------+
1 row in set, 1 warning (0.00 sec)mysql>
mysql> select SQL_CACHE * from test1 WHERE id = 1;
+------+--------+
| id   | name   |
+------+--------+
|    1 | decade |
+------+--------+
1 row in set, 1 warning (0.00 sec)mysql>
mysql> show profiles;
+----------+------------+--------------------------------------------+
| Query_ID | Duration   | Query                                      |
+----------+------------+--------------------------------------------+
|        1 | 0.00017600 | SELECT DATABASE()                          |
|        2 | 0.00025400 | show databases                             |
|        3 | 0.00007900 | show tables                                |
|        4 | 0.00016950 | select * from test1                        |
|        5 | 0.00022650 | select * from test1                        |
|        6 | 0.00320425 | select SQL_CACHE * from test1 WHERE id = 1 |
|        7 | 0.00004550 | select SQL_CACHE * from test1 WHERE id = 1 |
+----------+------------+--------------------------------------------+
7 rows in set, 1 warning (0.00 sec)mysql>
mysql> show profile;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000018 |
| Waiting for query cache lock   | 0.000002 |
| starting                       | 0.000001 |
| checking query cache for query | 0.000006 |
| checking privileges on cached  | 0.000002 |
| checking permissions           | 0.000008 |
| sending cached result to clien | 0.000006 |
| cleaning up                    | 0.000003 |
+--------------------------------+----------+
8 rows in set, 1 warning (0.00 sec)mysql>
mysql>
mysql>
mysql> show profile for query 6;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000024 |
| Waiting for query cache lock   | 0.000003 |
| starting                       | 0.000002 |
| checking query cache for query | 0.002889 |
| checking permissions           | 0.000014 |
| Opening tables                 | 0.000017 |
| init                           | 0.000020 |
| System lock                    | 0.000007 |
| Waiting for query cache lock   | 0.000002 |
| System lock                    | 0.000014 |
| optimizing                     | 0.000088 |
| statistics                     | 0.000014 |
| preparing                      | 0.000010 |
| executing                      | 0.000001 |
| Sending data                   | 0.000030 |
| end                            | 0.000002 |
| query end                      | 0.000005 |
| closing tables                 | 0.000004 |
| freeing items                  | 0.000031 |
| Waiting for query cache lock   | 0.000003 |
| freeing items                  | 0.000012 |
| Waiting for query cache lock   | 0.000001 |
| freeing items                  | 0.000001 |
| storing result in query cache  | 0.000002 |
| cleaning up                    | 0.000010 |
+--------------------------------+----------+
25 rows in set, 1 warning (0.00 sec)mysql>
mysql>
mysql> select SQL_NO_CACHE * from test1 WHERE id = 2;
+------+--------+
| id   | name   |
+------+--------+
|    2 | 十年   |
+------+--------+
1 row in set, 1 warning (0.00 sec)mysql>
mysql> show profile;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000078 |
| checking permissions | 0.000007 |
| Opening tables       | 0.000020 |
| init                 | 0.000023 |
| System lock          | 0.000007 |
| optimizing           | 0.000009 |
| statistics           | 0.000015 |
| preparing            | 0.000011 |
| executing            | 0.000002 |
| Sending data         | 0.000041 |
| end                  | 0.000004 |
| query end            | 0.000007 |
| closing tables       | 0.000006 |
| freeing items        | 0.000013 |
| cleaning up          | 0.000014 |
+----------------------+----------+
15 rows in set, 1 warning (0.00 sec)mysql>

4、数据库缓冲池

  • 因为磁盘I/O会消耗很多时间,所以DBMS会申请使用内存作为数据缓冲池(数据库缓冲池和查询缓存不是一回事),减少直接与磁盘进行I/O
  • InnoDB是以页为单位来管理存储空间的,我们进行的增删查改操作本质上都是在访问内存中一页一页的数据
  • 当执行更新操作时,会先刷新缓冲池中的数据,然后再按照一定的频率同步到磁盘的文件系统
  • 那如果同步到一半断电了怎么办?那就要用到下面两个文件
    • Redo.log—记录要重新同步的动作
    • Undo.log—记录要回滚的动作

在多线程情况下,可能要申请多个buffer pool,通过改变变量innodb_buffer_pool_instances为每个线程去申请独立的内存空间,避免相互影响

mysql> show variables like '%innodb_buffer_pool_instances';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_buffer_pool_instances | 1     |
+------------------------------+-------+
1 row in set (0.00 sec)mysql>

查看缓冲池大小innodb_buffer_pool_size
当buffer pool实例数量发生变化时,每个实例分配到的缓冲池大小是此变量/instance数量

mysql> show variables like '%innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+
1 row in set (0.00 sec)mysql>

二、存储引擎

1、存储引擎的查看

1)如下所示,我们可以查看当前系统默认存储引擎和系统支持哪些存储引擎
Transactions:是否支持事务
XA:是否支持分布式事务
Savepoints:保存点,回滚时使用

mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| ndbcluster         | NO      | Clustered, fault-tolerant tables                               | NULL         | NULL | NULL       |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| ndbinfo            | NO      | MySQL Cluster system information storage engine                | NULL         | NULL | NULL       |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
11 rows in set (0.00 sec)mysql>
mysql>
mysql> select @@default_storage_engine;
+--------------------------+
| @@default_storage_engine |
+--------------------------+
| InnoDB                   |
+--------------------------+
1 row in set (0.00 sec)mysql>

2)在建表时,如果没有显式指明存储引擎,那么就会使用系统默认的存储引擎

CREATE TABLE table_name(id INT,name VARCHAR(20)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2、存储引擎的差别

1)InnoDB

  • 优势:
    • 支持外键
    • InnoDB是MySQL的默认事务型引擎,它被设计用于处理大量的短期事务,可以保证事务的完整提交和回滚
    • 如果业务涉及大量更新和删除操作,推荐使用InnoDB
    • InnoDB是行级锁,操作时只锁住某一行的数据,不影响其他行,适合高并发的场景。而MyISAM是表级锁,即使操作一条记录也会锁住整个表,不适合高并发
  • 劣势:
    • 对比MyISAM,InnoDB在写数据方面的效率差一些,并且InnoDB会占用更多的磁盘空间保存数据和索引
    • MyISAM索引和数据是独立开的,只缓存索引。InnoDB因为索引和数据都在一个文件中,所以不仅缓存索引还缓存真实数据,对内存要求较高,内存大小对性能会有很大影响

2)MyISAM

  • 优势:访问速度快,对事务没有安全要求且主要以SELECT、INSERT为主的应用比较适合
  • 劣势:不支持外键、事务、行级锁,所以崩溃后无法安全恢复

两种存储引擎的数据结构可以参考博主之前写的【MySQL】Linux下MySQL的目录结构、用户、权限与角色,此博客第一节介绍了两种存储引擎的数据结构

如有错误,欢迎指正!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/42427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git 一种分布式版本控制系统

Git 是一种分布式版本控制系统,用于管理和追踪文件的修改历史。它具有以下基本概念和使用方式: 仓库(Repository):Git 将文件存储在仓库中,并记录文件的修改历史。仓库可以是本地仓库或远程仓库&#xff0c…

Python字符串处理常用的30种操作

我们平时编写代码时,经常需要对字符串进行处理,本文详细介绍Python处理字符串常用的30种操作,并给出了对应的代码。 分割 使用split()方法将字符串按照指定的分隔符进行分割。 s "Hello,World" result s.split(","…

国产AI芯片被撕下遮羞布,宁买阉割八成性能的NVIDIA,也不买国产

曾经有传言指有国产AI芯片大受欢迎,还卖出了100万片,不过半年多时间过去,海外分析机构指出国内的互联网企业纷纷抢购NVIDIA阉割八成性能的H20,至于国产AI芯片则不获欢迎。 导致如此结果,在于NVIDIA拥有许多独特的优势&…

什么是voc数据,和coco数据的区别是什么?

Pascal VOC 数据集格式 Pascal VOC 数据集的标注文件使用 XML 格式&#xff0c;每个图像对应一个 XML 文件&#xff0c;文件内容包含图像的元数据信息和目标的标注信息。XML 文件结构如下&#xff1a; <annotation><folder>VOC2007</folder><filename&g…

【工具问题】macOS Ventura 下如何开启NTFS移动硬盘读写?

花了半小时&#xff0c;网上检索了各种解决方案&#xff0c;发现还是下面这种方案可行&#xff0c;mark下方便下次遇到问题能更快速解决&#xff5e; macOS Ventura 下如何开启NTFS移动硬盘读写&#xff1f;

论文略读: LLaMA Pro: Progressive LLaMA with Block Expansion

ACL 2024 人类通常在不损害旧技能的情况下获得新技能 然而&#xff0c;对于大型语言模型&#xff08;LLMs&#xff09;&#xff0c;例如从LLaMA到CodeLLaMA&#xff0c;情况正好相反。深度学习笔记&#xff1a;灾难性遗忘-CSDN博客——>论文提出了一种用于LLMs的新的预训练…

Nettyの源码分析

本篇为Netty系列的最后一篇&#xff0c;按照惯例会简单介绍一些Netty相关核心源码。 1、Netty启动源码分析 代码就使用最初的Netty服务器案例&#xff0c;在bind这一行打上断点&#xff0c;观察启动的全过程&#xff1a; 由于某些方法的调用链过深&#xff0c;节约篇幅&#xf…

昇思MindSpore学习笔记4-03生成式--Diffusion扩散模型

摘要&#xff1a; 记录昇思MindSpore AI框架使用DDPM模型给图像数据正向逐步添加噪声&#xff0c;反向逐步去除噪声的工作原理和实际使用方法、步骤。 一、概念 1. 扩散模型Diffusion Models DDPM(denoising diffusion probabilistic model) &#xff08;无&#xff09;条件…

【嵌入式DIY实例-ESP8266篇】-LCD ST7735显示BMP280传感器数据

LCD ST7735显示BMP280传感器数据 文章目录 LCD ST7735显示BMP280传感器数据1、硬件准备与接线2、代码实现本文介绍如何将 ESP8266 NodeMCU 板 (ESP-12E) 与 Bosch Sensortec 的 BMP280 气压和温度传感器连接。 NodeMCU 微控制器 (ESP8266EX) 从 BMP280 传感器读取温度和压力值,…

普通Java工程如何在代码中引用docker-compose.yml中的environment值

文章目录 一、概述二、常规做法1. 数据库配置分离2. 代码引用配置3. 编写启动类4. 支持打包成可执行包5. 支持可执行包打包成docker镜像6. docker运行 三、存在问题分析四、改进措施1. 包含environment 变量的编排文件2. 修改读取配置文件方式3. 为什么可以这样做 五、运行效果…

如何正确使用Redisson实现分布式锁

分布式锁主要用于保证在分布式系统中&#xff0c;对共享资源的互斥访问&#xff0c;防止多个进程同时操作造成数据不一致。Redis实现分布式锁具备高性能和高可靠性的优势。接下来&#xff0c;我将详细描述如何在Spring Boot项目中使用Redis实现分布式锁。 常见的共享资源举例 …

python库(6):Pygments库

1 Pygments介绍 在软件开发和文档编写中&#xff0c;代码的可读性是至关重要的一环。无论是在博客文章、技术文档还是教程中&#xff0c;通过代码高亮可以使程序代码更加清晰和易于理解。而在Python世界中&#xff0c;Pygments库就是这样一个强大的工具&#xff0c;它能够将各…

ValueError: Expected EmbeddingFunction.__call__ to have the following signature

题意&#xff1a; 使用 langchain 时&#xff0c;特别是在定义或调用嵌入函数&#xff08;Embedding Function&#xff09;时&#xff0c;签名&#xff08;函数的参数列表和返回类型&#xff09;不符合预期 问题背景&#xff1a; When I try to pass a Chroma Client to Lang…

搭建论坛和mysql数据库安装和php安装

目录 概念 步骤 安装mysql8.0.30 安装php 安装Discuz 概念 搭建论坛的架构&#xff1a; lnmpDISCUZ l 表示linux操作系统 n 表示nginx前端页面的web服务 m 表示 mysql 数据库 用来保存用户和密码以及论坛的相关内容 p 表示php 动态请求转发的中间件 步骤 &#xff…

【C++深度探索】:继承(定义赋值兼容转换作用域派生类的默认成员函数)

✨ 愿随夫子天坛上&#xff0c;闲与仙人扫落花 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;C学习 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞…

动态数组(java)

package arraList;public interface AbstractArray<E> {int size();//元素数量boolean isEmpty();//是否为空boolean contains(E element);//是否包含某个元素void add(E element);//添加元素到最后面E get(int index);//返回index位置对应的元素E set(int index,E eleme…

CVE-2024-0603 漏洞复现

CVE-2024-0603 源码&#xff1a;https://gitee.com/dazensun/zhicms 开题&#xff1a; CVE-2024-0603描述&#xff1a;ZhiCms up to 4.0版本的文件app/plug/controller/giftcontroller.php中存在一处未知漏洞。攻击者可以通过篡改参数mylike触发反序列化&#xff0c;从而远程…

【c++设计模式20】行为模式5:备忘录模式(Memento Pattern)

【c++设计模式20】行为模式5:备忘录模式(Memento Pattern) 一、定义二、适用场景三、过程四、备忘录模式类图五、C++示例代码六、使用注意事项原创作者:郑同学的笔记 原创地址:https://zhengjunxue.blog.csdn.net/article/details/132766604 qq技术交流群:921273910 类型…

python脚本“文档”撰写——“诱骗”ai撰写“火火的动态”python“自动”脚本文档

“火火的动态”python“自动”脚本文档&#xff0c;又从ai学习搭子那儿“套”来&#xff0c;可谓良心质量&#x1f44d;&#x1f44d;。 (笔记模板由python脚本于2024年07月07日 15:15:33创建&#xff0c;本篇笔记适合喜欢钻研python和页面源码的coder翻阅) 【学习的细节是欢悦…

【学习笔记】程序设计竞赛

程序设计竞赛 文章目录 程序设计竞赛0x00 基本操作指南0x01 算法分析0x02 STL和基本数据结构栈队列集合map 0x03 排序插入排序归并排序&#xff08;Merge Sort)快速排序 0x04 搜索技术BFSDFS回溯与剪枝 深度迭代ID A*A star双向广搜 0x05 递推方程0x06 高级数据结构并查集二叉树…