了解MyISAM记录结构

inv*_*sal 6 mysql database architecture myisam

我试图了解MyISAM如何实际存储其记录以及在记录插入和记录删除后如何维护其结构.我看过以下链接:

我想确定我是否理解正确,如果不对,请纠正我.

固定大小的记录

MyISAM固定大小的记录

  • 删除标记确定是删除还是不删除记录.
  • 记录标题保存行的哪一列包含NULL值
  • 数据长度是固定的.

可变大小的记录

在此输入图像描述

  • 删除标记替换为BLOCK_DELETED块类型
  • 记录头保存数据长度和未使用数据的长度

在此输入图像描述

  • 单个记录可以分成由溢出指针连接的多个块.

删除

在此输入图像描述

  • 对于可变大小的记录,将块类型更改为BLOCK_DELETED
  • 通过使新删除的记录的先前指针指向上次删除的记录来维护所有已删除记录的双链表.然后,最后删除的记录的下一个指针指向新删除的记录.
  • 对于固定大小的记录,只需将删除标记更改为已删除.(不确定他们是否使用双链表来连接所有已删除的记录和固定大小的记录)

插入

  • 如果没有未使用的空间(已删除的记录),请将数据附加到文件的末尾
  • 如果有未使用的空间适合新插入的记录,请在此处写入新记录.
  • 如果有未使用的空间远远大于新插入的记录,则拆分为两个记录:新记录和已删除记录.
  • 如果有未使用的空间小于新插入的记录,则在那里写入数据,有溢出指针指向其他块的未经处理的数据.

更新

  • 如果用户使用更长的数据更新现有数据会怎样?MyISAM会将记录标记为已删除并找到适合新数据的位置,或者只是使用溢出指针指向不合适的数据?

再回顾一下这个问题

我想确定我是否理解正确,如果不对,请纠正我.

其他问题

  • 如果表已被删除并插入很多次,因为记录结构可能充满溢出指针和未使用的空间,它会非常低效吗?

Rol*_*DBA 5

您在有关 MyISAM 的问题中的信息是正确的。但是,我想解决您的另外两个问题:

最新问题

如果用户用更长的数据更新现有数据怎么办?MyISAM 会将记录标记为已删除并找到适合新数据的位置还是只是使用溢出指针指向未适合的数据?

根据

数据包

第 10 章:“存储引擎” 第 196 页 第 7 段说

对于可变长度的记录,格式更复杂。第一个字节包含描述记录子类型的特殊代码。后续字节的含义因每个子类型而异,但共同的主题是有一个字节序列,其中包含记录的长度、块中未使用的字节数、NULL 值指示符标志以及可能指向如果记录不适合先前创建的空间并且必须拆分,则记录的延续。当一条记录被删除,并且要插入其位置的新记录超过原始记录的大小时,就会发生这种情况。可以通过研究storage/myisam/mi_dynrec.c中的switch语句in_mi_get_block_info()来详细了解不同代码的含义。

根据该段落,只有当要插入的新数据无法放入先前分配的块时,旧记录才会被链接数据覆盖。这可能会导致许多臃肿的行。

附加问题

如果表被多次删除和插入,因为记录结构可能充满溢出指针和未使用的空间,效率会非常低吗?

从我之前的回答来看,会有很多块

  • 空间块
  • 记录的长度
  • 块中未使用的字节数
  • NULL 值指示符标志
  • 如果记录不适合先前创建的空间并且必须拆分,则可能是指向记录延续的指针

此类记录链接将从插入过大数据的每一行的前面开始。这会.MYD很快使 MyISAM 表文件膨胀。

建议

MyISAM 的默认行格式是动态的。当一个表是动态的并且经历了大量的插入、更新和删除时,这样的表需要优化

OPTIMIZE TABLE mytable;
Run Code Online (Sandbox Code Playgroud)

有一种替代方法:将表的行格式切换为“固定”。这样,所有行的大小都相同。这是使行格式固定的方式:

ALTER TABLE mytable ROW_FORMAT=Fixed;
Run Code Online (Sandbox Code Playgroud)

即使使用固定行格式,也必须花费时间来定位可用记录,但时间将是 O(1) 搜索时间(通俗地说,无论有多少行,定位可用记录都需要相同的时间该表有或有多少已删除的行)。您可以通过启用concurrent_insert来绕过该步骤,如下所示:

将此添加到 my.cnf

[mysqld]
concurrent_insert = 2
Run Code Online (Sandbox Code Playgroud)

不需要重启 MySQL。赶紧跑

mysql> SET GLOBAL concurrent_insert = 2;
Run Code Online (Sandbox Code Playgroud)

这将导致所有 INSERT 都转到表的后面而不寻找可用空间。

固定行表的优势

  • INSERT、UPDATE 和 DELETE 会更快一些
  • SELECT 快 20-25%

以下是我关于 SELECT 因行格式固定而更快的一些帖子

固定行表的缺点

在大多数情况下,当您运行 时ALTER TABLE mytable ROW_FORMAT=Fixed;,该表可能会增长 80-100%。该.MYI文件(MyISAM 表的索引页)也将以相同的速度增长。

结语

如果您想要 MyISAM 表的速度并且可以使用更大的表,则需要我的替代建议。如果要为每个 MyISAM 表节省空间,请保留行格式(动态)。您将不得不OPTIMIZE TABLE mytable;使用动态表更频繁地压缩表。