【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的目录结构、用户、权限与角色,此博客第一节介绍了两种存储引擎的数据结构

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Facebook数据仓库的变迁与启示

❃博主首页 &#xff1a; <码到三十五> ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a; <搬的每块砖&#xff0c;皆为峰峦之基&#xff1b;公众号搜索(码到…

史上最全的自抗扰控制(ADRC)学习资料

史上最全的自抗扰控制&#xff08;ADRC&#xff09;学习资料 需要的私信我~ 需要的私信我~ 需要的私信我~ ​ 本文将作者近些年来学习ADRC算法的学习资料进行汇总&#xff0c;整理了这一版相对较全的学习资料&#xff0c;包含参考文献以及仿真案例&#xff0c;适合初学者入门&…

STM32实现看门狗(HAL库)

文章目录 一. 看门狗1. 独立看门狗&#xff08;IWDG&#xff09;1.1 原理1.2 相关配置1.3 相关函数 2. 窗口看门狗&#xff08;WWDG&#xff09;2.1 原理2.2 相关配置2.3 相关函数 一. 看门狗 单片机在日常工作中常常会因为用户配置代码出现BUG&#xff0c;而导致芯片无法正常工…

21天学通C++:第九、十章节

第九章&#xff1a;类和对象 带默认值的构造函数参数 注意&#xff1a;默认构造函数是调用时可不提供参数的构造函数&#xff0c;而并不一定是不接受任何参数的构造函数。 因此&#xff0c;下面的构造函数虽然有两个参数&#xff0c;但它们都有默认值&#xff0c;因此也是默认…

CurrentHashMap巧妙利用位运算获取数组指定下标元素

先来了解一下数组对象在堆中的存储形式【数组长度&#xff0c;数组元素类型信息等】 【存放元素对象的空间】 Ma 基础信息实例数据内存填充Mark Word,ClassPointer,数组长度第一个元素第二个元素固定的填充内容 所以我们想要获取某个下标的元素首先要获取这个元素的起始位置…

Java 有什么必看的书?

Java必看经典书有这两本&#xff1a; 1、Java核心技术速学版&#xff08;第3版&#xff09; 经典Java开发基础书CoreJava速学版本&#xff01;Java入门优选书籍&#xff0c;更新至Java17&#xff0c;内容皆是精华&#xff0c;让Java学习更简单&#xff0c;让Java知识应用更快速…

fasttext工具介绍

fastText是由Facebook Research团队于2016年开源的一个词向量计算和文本分类工具。尽管在学术上并未带来巨大创新&#xff0c;但其在实际应用中的表现却非常出色&#xff0c;特别是在文本分类任务中&#xff0c;fastText往往能以浅层网络结构取得与深度网络相媲美的精度&#x…

STM32CubeMX实现4X5矩阵按键(HAL库实现)

为了实现计算器键盘&#xff0c;需要使用4X5矩阵按键&#xff0c;因此&#xff0c;我在4X4矩阵键盘上重新设计了一个4X5矩阵按键。原理图如下&#xff1a; 原理描述&#xff1a; 4X5矩阵按键&#xff0c;可以设置4个引脚为输出&#xff0c;5个引脚为输入模式&#xff0c;4个引…

MPS---MPQ86960芯片layout设计总结

MPQ86960 是一款内置功率 MOSFET 和栅极驱动的单片半桥。它可以在宽输入电压 (VIN) 范围内实现高达 50A 的连续输出电流 (IOUT)&#xff0c;通过集成MOSFET 和驱动可优化死区时间 (DT) 并降低寄生电感&#xff0c;从而实现高效率。 MPQ86960 兼容三态输出控制器&#xff0c;另…

Ubantu22.04 通过FlatPak安装微信

Ubuntu22.04 下使用Flatpak稳定安装微信&#xff01; 国际惯例&#xff0c;废话不多说&#xff0c;先上效果图。为啥使用Flatpak,因为Wechat官方只在FlatPak发布了最新的版本。之前使用了Wine以及Dock安装Wechat,效果都不是很理想&#xff0c;bug很多。所以使用了FlatPak。 Fl…

GRPC使用之ProtoBuf

1. 入门指导 1. 基本定义 Protocol Buffers提供一种跨语言的结构化数据的序列化能力&#xff0c;类似于JSON&#xff0c;不过更小、更快&#xff0c;除此以外它还能用用接口定义(IDL interface define language)&#xff0c;通protoc编译Protocol Buffer定义文件&#xff0c;…

【Spring Cloud】微服务的简单搭建

文章目录 &#x1f343;前言&#x1f384;开发环境安装&#x1f333;服务拆分的原则&#x1f6a9;单一职责原则&#x1f6a9;服务自治&#x1f6a9;单向依赖 &#x1f340;搭建案例介绍&#x1f334;数据准备&#x1f38b;工程搭建&#x1f6a9;构建父子工程&#x1f388;创建父…

关闭vue3中脑瘫的ESLine

在创建vue3的时候脑子一抽选了ESLine,然后这傻卵子ESLine老是给我报错 博主用的idea开发前端 ,纯粹是用不惯vscode 关闭idea中的ESLine,这个只是取消红色波浪线, 界面中的显示 第二步,在vue.config.js中添加 lintOnSave: false 到这里就ok了,其他的我试过了一点用没有

Google Java Style Guide深度解读:打造优雅的代码艺术

在软件工程的世界里&#xff0c;代码不仅仅是实现功能的工具&#xff0c;它也是团队之间沟通的桥梁&#xff0c;是软件质量和可维护性的直接反映。Google Java Style Guide作为一套广受认可的编码规范&#xff0c;不仅定义了代码的书写规则&#xff0c;更深刻地影响着Java开发者…

绿色金融相关数据合集(2007-2024年 具体看数据类型)

数据类型&#xff1a; 1.绿色债券数据&#xff1a;2014-2023 2.绿色信贷相关数据&#xff1a;2007-2022 3.全国各省及地级市绿色金融指数&#xff1a;1990-2022 4.碳排放权交易明细数据&#xff1a;2013-2024 5.绿色金融试点DID数据&#xff1a;2010-2023 数据来源&#…

python操作SQLite3数据库进行增删改查

python操作SQLite3数据库进行增删改查 1、创建SQLite3数据库 可以通过Navicat图形化软件来创建: 2、创建表 利用Navicat图形化软件来创建: 存储在 SQLite 数据库中的每个值(或是由数据库引擎所操作的值)都有一个以下的存储类型: NULL. 值是空值。 INTEGER. 值是有符…

Linux—网络设置

目录 一、ifconfig——查看网络配置 1、查看网络接口信息 1.1、查看所有网络接口 1.2、查看具体的网络接口 2、修改网络配置 3、添加网络接口 4、禁用/激活网卡 二、hostname——查看主机名称 1、查看主机名称 2、临时修改主机名称 3、永久修改主机名称 4、查看本…

【python】pyqt5大学生成绩信息管理系统-图形界面(源码+报告)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

基于支持向量机、孤立森林和LSTM自编码器的机械状态异常检测(MATLAB R2021B)

异常检测通常是根据已有的观测数据建立正常行为模型&#xff0c;从而将不同机制下产生的远离正常行为的数据划分为异常类&#xff0c;进而实现对异常状态的检测。常用的异常检测方法主要有&#xff1a;统计方法、信息度量方法、谱映射方法、聚类方法、近邻方法和分类方法等。 …