MySQL查询执行(八):Memory引擎

news2025/1/12 12:22:53

思考:两个group by语句都用了order bynull, 为什么使用内存临时表得到的语句结果里, 0这个值在最后一行; 而使用磁盘临时表得到的结果里, 0这个值在第一行?

答:答案对应第一小节:内存表的数据组织结构。

内存表的数据组织结构


假设有以下两张表t1、t2,其中表t1是Memory引擎,表t2是InnoDB引擎。

-- 创建表t1,t2,分别使用Memory引擎和InnoDB引擎;
create table t1(id int primary key,c int) engine=Memory;
create table t2(id int primary key,c int) engine=innodb;
insert into t1values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
insert into t2values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);

-- 执行查询语句,得到结果如下图:
select * from t1;
select * from t2;

结果如下:

可以看到, 内存表t1的返回结果里面0在最后一行, 而InnoDB表t2的返回结果里0在第一行。

表t2是InnoDB表,其数据就放在主键索引树上,主键索引是B+树。数据组织方式如下:

主键索引上的值是有序存储的,在执行select *的时候, 就会按照叶子节点从左到右扫描, 所以得到的结果里, 0就出现在第一行。

表t1是Memory表,而Memory表的数据和索引是分开的。数据组织方式如下:

从图中可以看到,内存表的数据部分以数组的方式单独存放,而主键id索引里,存的是每个数据的位置。主键id是hash索引,可以看到索引上的key并不是有序的。

在对表t1执行select *的时候, 走的是全表扫描, 也就是顺序扫描这个数组。 因此, 0就是最后一个被读到, 并放入结果集的数据。

问1:什么是索引组织表?什么是堆组织表?

  1. InnoDB引擎把数据放在主键索引上, 其他索引上保存的是主键id。 这种方式, 我们称之为索引组织表(IndexOrganizied Table) 。
  2. 而Memory引擎采用的是把数据单独存放, 索引上保存数据位置的数据组织形式, 我们称之为堆组织表(Heap Organizied Table) 。

问2:InnoDB和Memory引擎有哪些区别?

  1. InnoDB表的数据总是有序存放的, 而内存表的数据就是按照写入顺序存放的;
  2. 当数据文件有空洞的时候, InnoDB表在插入新数据的时候, 为了保证数据有序性, 只能在固定的位置写入新值, 而内存表找到空位就可以插入新值。
  3. 数据位置发生变化的时候, InnoDB表只需要修改主键索引, 而内存表需要修改所有索引。
  4. InnoDB表用主键索引查询时需要走一次索引查找, 用普通索引查询的时候, 需要走两次索引查找。 而内存表没有这个区别, 所有索引的“地位”都是相同的。
  5. InnoDB支持变长数据类型, 不同记录的长度可能不同; 内存表不支持Blob 和 Text字段, 并且即使定义了varchar(N), 实际也当作char(N), 也就是固定长度字符串来存储, 因此内存表的每行数据长度相同。

注:因为Memory表的主键索引是哈希索引,因此如果执行范围查询,只能走全表扫描。

hash索引和B-Tree索引


内存表也支持B-Tree索引。

在id列上创建B-Tree索引,语法如下:

alter table t1 add index a_btree_index using btree (id);

此时,表t1的数据组织形式如下:

问1:为什么内存表速度快?

  1. 内存表的所有数据都保存在内存中,而内存的读写速度总是比磁盘块。
  2. Memory引擎支持hash索引。

问2:既然内存表速度快,为什么生产环境不建议使用内存表?

  1. 锁粒度问题。内存表不支持行锁,只支持表锁,对并发访问不友好。一张表的更新,会阻塞所有在这个表上的读写操作。
  2. 数据持久化问题。数据库重启的时候,所有的内存表都会被清空,可能导致主从数据不一致。

内存表的锁


内存表不支持行锁,只支持表锁。

因此,如果一张表有更新,就会堵住其它所有在这个表上的读写操作。

模拟内存表的表级锁,示例:

在这个执行序列里, session A的update语句要执行50秒, 在这个语句执行期间session B的查询会进入锁等待状态。 session C的show processlist 结果输出如下:

跟行锁比起来, 表锁对并发访问的支持不够好。 所以, 内存表的锁粒度问题, 决定了它在处理并发事务的时候, 性能也不会太好。

数据持久性问题


如果数据库重启,所有的内存表都会被清空。

问:M-S架构下,使用内存表存在什么问题?

M-S基本架构如下:

看一下下面这个时序:

  1. 业务正常访问主库。
  2. 备库硬件升级, 备库重启, 内存表t1内容被清空。
  3. 备库重启后, 客户端发送一条update语句, 修改表t1的数据行, 这时备库应用线程就会报错“找不到要更新的行”。

内存表可能导致主备不一致。

由于MySQL知道重启后, 内存表的数据会丢失。 所以, 担心主库重启之后, 出现主备不一致, MySQL在实现上做了这样一件事儿: 在数据库重启之后, 往binlog里面写入一行DELETE FROM t1。

双M架构如下:

在备库重启的时候, 备库binlog里的delete语句就会传到主库, 然后把主库内存表的内容删除。这样你在使用的时候就会发现, 主库的内存表数据突然被清空了。

结论:无论是M-S架构,还是双M架构,内存表都不适合在生产环境上作为普通数据表使用。

内存表的使用场景


内存表的使用场景:作为临时表使用

1)临时表不会被其他线程访问,没有并发性的问题。

2)临时表重启后也是需要删除的,清空数据这个问题不存在。

3)备库的临时表也不会影响主库的用户线程。

4)操作临时表都是单个session线程,无需考虑并发问题。

小结:思考题


思考:假设你刚刚接手的一个数据库上, 真的发现了一个内存表。 备库重启之后肯定是会导致备库的内存表数据被清空, 进而导致主备同步停止。 这时, 最好的做法是将它修改成InnoDB引擎表。假设主库暂时不能修改引擎, 你可以加上什么自动化逻辑, 来避免主备同步停止呢?

1)假设的是主库暂时不能修改引擎,则先把备库的内存表引擎先都改成InnoDB。对于每个内存表,执行如下语句,避免备库重启的时候,数据丢失的问题。

set sql_log_bin=off;
alter table tbl_name engine=innodb;

2)主库重启后,会往binlog里面写“delete from tbl_name”,这个命令传到备库,备库的同名表数据也会被清空。因此,就不会出现主备同步停止的问题。

3)如果主库异常重启,触发了HA,之前修改过引擎的备库变成了主库。而旧主库变成了新备库,在新备库上把所有的内存表(这时候表里没数据)都改成InnoDB表。

所以,如果我们不能直接修改主库上的表引擎,可以配置一个自动巡检的工具,在备库上发现内存表就把引擎改了。

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

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

相关文章

canva 画图 UI 设计

起因, 目的: 来源: 客户需求。 目的: 用数据讲故事。 数据可以瞎编,图表一定要漂亮。 文件分享地址 读者可以在此文件的基础上,继续编辑。 效果图 过程: 我还是喜欢 canva. figma, 我用的时候,每每都想…

ES分词环境实战

文章目录 安装下载1.1 下载镜像1.2 单节点启动 防火墙设置异常处理【1】iptable链路中断 参考文档 参加完2024年11月软考,对ES的分词进行考查,前期有【 Docker 环境下安装部署 Elasticsearch 和 kibana】和【 Docker 环境下为 Elasticsearch 安装IK 分…

论文精读: PRB LiVSe2 Zigzag链序实验与理论计算

DOI: 10.1103/PhysRevB.108.094107 摘要节选 在具有轨道自由度的过渡金属化合物中,组成元素在低温下自组装形成分子的现象普遍存在。 在本研究中从实验和理论两方面讨论了钒二维三角形晶格层状LiVX2 (X O, S, Se)体系中出现的三…

修改一下达梦disql 提示符

经常用disql的有时某些信息希望提示一下,默认的只显示SQL> 为了方便使用,可以在 glogin.sql 中增加些内容。 vi $DM_HOME/bin/disql_conf/glogin.sql增加以下几行 set time on set lineshow offcol global_name new_value global_name SELECT ins…

【蓝桥杯备赛】123(前缀和的复杂应用)

5. 前缀和的复杂应用 5.1. 123(4 星) 5.1.1. 题目解析 这道题仍然是求一段区间的和,很容易能够想到前缀和找规律: 1------------------1 号块 1 2----------------2 号块 1 2 3--------------3 号块 1 2 3 4------------4 号…

机器学习—学习曲线

学习曲线是帮助理解学习算法如何工作的一种方法,作为它所拥有的经验的函数。 绘制一个符合二阶模型的学习曲线,多项式或二次函数,画出交叉验证错误Jcv,以及Jtrain训练错误,所以在这个曲线中,横轴将是Mtrai…

数据库基础(MySQL)

1. 数据库基础 1.1 什么是数据库 存储数据用文件就可以了,为什么还要弄个数据库? 文件保存数据有以下几个缺点: 文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便 数据库存储介质: 磁盘内存 为…

2024年11月HarmonyOS应用开发者基础认证全新题库

注意事项:切记在考试之外的设备上打开题库进行搜索,防止切屏三次考试自动结束,题目是乱序,每次考试,选项的顺序都不同 更新时间:2024年11月1日 这是基础认证题库,不是高级认证题库注意看清楚标…

静态时序分析--时序约束

目录 1.时钟约束1.1创建时钟1.2.生成时钟1.3虚拟时钟1.4 最小时钟脉宽 2.I/O延时约束2.1设置输入延时2.2设置输出延时 3.I/O环境建模约束3.1输入驱动建模3.2输出负载建模 4.时序例外4.1多周期路径设置(multicycle path)4.2伪路径设置(false_p…

51单片机基础05 实时时钟-思路及代码参考2、3

目录 一、思路二 1、原理图 2、代码 二、思路三 1、原理图 2、代码 一、思路二 所有设定功能相关的操作均在矩阵键盘进行实现&#xff0c;并在定时器中扫描、计数等 1、原理图 2、代码 #include <AT89X52.h> //调用51单片机的头文件 //------------------…

【C++篇】深入剖析C++ Vector底层源码及实现机制

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

【代码pycharm】动手学深度学习v2-04 数据操作 + 数据预处理

数据操作 数据预处理 1.数据操作运行结果 2.数据预处理实现运行结果 第四课链接 1.数据操作 import torch # 张量的创建 x1 torch.arange(12) print(1.有12个元素的张量&#xff1a;\n,x1) print(2.张量的形状&#xff1a;\n,x1.shape) print(3.张量中元素的总数&#xff1…

鸿蒙HarmonyOS开发:一次开发,多端部署(工程级)三层工程架构

文章目录 一、工程创建1、先创建出最基本的项目工程。2、新建common、features、 products 目录 二、工程结构三、依赖关系1、oh-package.json52、配置ohpm包依赖 四、引用ohpm包中的代码1、定义共享资源2、在common模块index文件中导出3、在phone模块oh-package.json5文件中引…

NLP论文速读(EMNLP 2023)|工具增强的思维链推理

论文速读|ChatCoT: Tool-Augmented Chain-of-Thought Reasoning on Chat-based Large Language Models 论文信息&#xff1a; 简介&#xff1a; 本文背景是关于大型语言模型&#xff08;LLMs&#xff09;在复杂推理任务中的表现。尽管LLMs在多种评估基准测试中取得了优异的成绩…

uniapp vue3小程序报错Cannot read property ‘__route__‘ of undefined

在App.vue里有监听应用的生命周期 <script>// 只能在App.vue里监听应用的生命周期export default {onError: function(err) {console.log(AppOnError:, err); // 当 uni-app 报错时触发}} </script>在控制台打印里无意发现 Cannot read property ‘__route__‘ of …

第17章 子查询

一、介绍子查询 1.1 介绍 子查询指一个查询语句嵌套在另一个查询语句内部的查询&#xff0c;这个特性从MySQL 4.1开始引入。 SQL 中子查询的使用大大增强了 SELECT 查询的能力&#xff0c;因为很多时候查询需要从结果集中获取数据&#xff0c;或者需要从同一个表中先计算得出一…

蓝队技能-应急响应篇日志自动采集日志自动查看日志自动化分析Web安全内网攻防工具项目

知识点&#xff1a; 1、应急响应-系统日志收集-项目工具 2、应急响应-系统日志查看-项目工具 3、应急响应-日志自动分析-项目工具 演示案例-蓝队技能-工具项目-自动日志采集&自动日志查看&自动日志分析 系统日志自动采集-观星应急工具(Windows系统日志) SglabIr_Co…

【西瓜书】线性判别分析-LDA

线性判别分析&#xff08;Linear Discriminant Analysis&#xff0c;简称LDA&#xff09;是一种经典的线性学习方法。在二分类问题上&#xff0c;因为最早由Fisher提出&#xff0c;也称“Fisher判别分析”。 严格说来&#xff0c;LDA 与 Fisher判别分析稍有不同&#xff0c;LDA…

Photino:通过.NET Core构建跨平台桌面应用程序,.net国产系统

一、Photino.NET简介&#xff1a; 最近发现了一个不错的框架 Photino.Net 一份代码运行&#xff0c;三个平台 windows max linux &#xff0c;其中windows10,windows11,ubuntu 18.04,ubuntu 20.04 已测试均可以。mac 因为没有相关电脑没有测试。 github:https://github.com/t…

湘潭大学软件工程算法设计与分析考试复习笔记(四)

回顾 湘潭大学软件工程算法设计与分析考试复习笔记&#xff08;一&#xff09;湘潭大学软件工程算法设计与分析考试复习笔记&#xff08;二&#xff09;湘潭大学软件工程算法设计与分析考试复习笔记&#xff08;三&#xff09; 前言 现在是晚上十一点&#xff0c;我平时是十…