mysql的存储碎片

news/2024/12/26 22:44:40/

mysql_1">什么是mysql的存储碎片

MySQL 的存储碎片是指在数据库存储数据的过程中,数据文件(如 InnoDB 的表空间文件或 MyISAM 的数据文件和索引文件)或者内存缓冲池中,数据的存储变得不连续,出现了一些零散的、未被充分利用的小空间。这些小空间由于各种原因不能有效地组合成连续的、可用于存储完整数据记录或数据块的空间

MySQL中的数据库表会存在物理存储碎片,这种情况通常发生在频繁执行插入、删除和更新操作的数据库中。这些操作会导致表中的数据页部分空间未被有效利用或数据在物理存储上的排列不连续,从而形成碎片。

存储碎片产生的方式

主要来源是数据的修改操作 insertupdate以及 delete

插入导致的碎片

InnoDB 存储引擎使用 B+树索引结构存储数据,并且数据通常按主键顺序存储。当我们的主键并不是顺序自增时,比如用UUID,那么新插入的数据行可能会导致页分裂现象。

什么是也分裂:
InnoDB 存储引擎使用的 B + 树索引为例,数据存储在叶子节点的数据页中,索引键值存储在非叶子节点的数据页中。当插入新的数据导致一个数据页(叶子节点)无法容纳新的数据时,这个数据页就会分裂成两个数据页。

页分裂会导致数据分散在磁盘上多个不同的位置。新创建的页可能在物理存储上与原始页相距甚远,呢么这些数据在物理上就不是连续的,那么就会存在碎片。

更新 导致的碎片

update操作导致数据行大小增加,而原位置周围没有足够的空间容纳更新后的行,这行数据可能会被移动到数据文件的其他部分,这样就会留下空闲位置,导致碎片。

比如字段通过设置的varchar可变长度,因此更新时行的数据大写小发生变化。对于定长的字段用char设置。

删除导致的碎片

delete 最容易导致碎片的,在 InnoDB中,delete执行后,只是给数据做了个标记,但空间并不会立即释放。这导致数据页中可能存在大量未使用的空间,增加了数据的分散程度,这就是碎片。

碎片的危害

增加磁盘 I/O 操作

当存在存储碎片时,数据在磁盘上的存储位置变得分散。例如,一个查询原本只需要读取一个连续的数据块就能获取所需信息,但由于碎片的存在,数据可能分布在多个不连续的磁盘位置。这就导致数据库在执行查询操作时,需要多次进行磁盘 I/O 操作来读取分散的数据。对于频繁查询的数据库系统,大量的额外磁盘 I/O 会显著降低系统的整体性能。

以一个存储客户订单信息的数据库为例,当查询某个客户的所有订单时,如果订单数据因为碎片而分散在多个数据页中,数据库需要从磁盘的不同位置读取这些数据页,相比数据连续存储时,读取时间会大大增加。

降低缓存效率

在 MySQL 中,缓冲池(如 InnoDB 缓冲池)用于缓存数据页和索引页,以减少磁盘 I/O。但是,碎片会使数据页和索引页在缓冲池中难以高效地缓存。由于碎片导致数据页不完整或部分空闲,缓冲池可能无法充分利用其空间来缓存完整的、经常使用的数据页。

假设缓冲池大小有限,有较多的碎片化数据页占用空间,而真正需要缓存的完整且频繁使用的数据页无法被加载进来,这就会降低缓存的效果,进而影响查询性能。因为更多的查询需要从磁盘而不是缓冲池中获取数据,增加了磁盘 I/O 的负担。

造成磁盘空间浪费

存储碎片使得磁盘空间无法得到有效利用。这些碎片空间单个可能较小,但随着时间的推移和操作的积累,它们会占用大量的磁盘空间。例如,在一个数据库表空间中,由于数据的删除和更新操作产生了许多小碎片,这些碎片空间加起来可能占据了相当大的磁盘容量,但却无法被有效地用于存储新的数据。

就好像一个仓库里有很多小的角落空间,由于形状不规则(类比碎片空间),无法放置完整的货物(数据),导致仓库空间利用率低下。

增加存储成本

如果因为碎片导致磁盘空间利用率低,为了存储相同数量的数据,可能需要购买更多的磁盘空间。对于大型企业级数据库系统,这会增加显著的存储成本。例如,一个数据中心存储大量数据库,如果数据库普遍存在碎片问题,需要不断增加磁盘阵列来满足存储需求,这涉及到硬件采购、能源消耗等诸多成本。

如何减少碎片的产生

  • 对于使用 InnoDB 存储引擎的表,采用自增主键,顺序插入存储数据的页中,避免数据无序插入导致的页分裂和碎片产生。
  • 批量插入数据,减少每次插入操作对存储结构的微小改变,从而降低碎片产生的可能性
  • OPTIMIZE TABLE命令可以重新组织表的数据页,减少碎片。
  • ALTER TABLE... ENGINE = InnoDB命令来重建索引,减少索引碎片对查询性能的影响
  • 适当调整InnoDB的配置参数,如页大小、填充因子、叶子页合并的阈值等,以优化数据库性能。

http://www.ppmy.cn/news/1558370.html

相关文章

Redis-十大数据类型

Reids数据类型指的是value的类型,key都是字符串 redis-server:启动redis服务 redis-cli:进入redis交互式终端 常用的key的操作 redis的命令和参数不区分大小写 ,key和value区分 查看当前库所有的key keys * 判断某个key是否存在 exists key 查看key是什…

问题小记-达梦数据库报错“字符串转换出错”处理

最近遇到一个达梦数据库报错“-6111: 字符串转换出错”的问题,这个问题主要是涉及到一条sql语句的执行,在此分享下这个报错的处理过程。 问题表现为:一样的表结构和数据,执行相同的SQL,在Oracle数据库中执行正常&…

使用Python探索量子机器学习

量子计算与机器学习的结合正在成为一个激动人心的研究领域。量子机器学习(Quantum Machine Learning, QML)利用量子计算的强大计算能力,提升传统机器学习算法的效率和性能。本文将以Python为例,介绍如何使用量子计算框架构建简单的…

HarmonyOS NEXT 实战之元服务:静态案例效果(二)

背景: 前几篇学习了元服务,后面几期就让我们开发简单的元服务吧,里面丰富的内容大家自己加,本期案例 仅供参考 先上本期效果图 ,里面图片自行替换 效果图代码案例如下: Index里面实现 import { authent…

云原生后端开发(一)

云原生后端开发 云原生(Cloud-Native)是指一种构建和运行应用程序的方式,它充分利用了云计算的特点,比如弹性伸缩、自动化部署、容器化等。在云原生的架构下,后端应用通常具备高度可扩展、可维护、易于自动化管理的特…

大数据新视界 -- Hive 数据生命周期管理:数据归档与删除策略(2 - 16 - 11)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

C# 第二阶段 modbus

1:nuget添加依赖 新建项目后,添加NModbus, 2:测试软件:Modbus slave ,新建一个从站,并连接 3:通信测试 4:本次学到的内容 4.1:用的DockPanel标签,使其能自适…

解决在vue3+vite+element-plus 中echarts在el-dialog无法正常显示问题

核心&#xff1a;在dom加载完成后调用echarts实例 的resize()方法 这里是一个例子 这里封装一个echarts <template><div class"container" ref"container"></div> </template> <script lang"ts" setup> import {…