我试图了解MyISAM如何实际存储其记录以及在记录插入和记录删除后如何维护其结构.我看过以下链接:
> MyISAM Dynamic Data File Layout
> MyISAM Record Structure
我想确定我是否理解正确,如果不对,请纠正我.
固定大小的记录
>删除标记确定是删除还是不删除记录.
>记录标题保存行的哪一列包含NULL值
>数据长度是固定的.
可变大小的记录
>删除标记替换为BLOCK_DELETED块类型
>记录头保存数据长度和未使用数据的长度
>单个记录可以分隔成由溢出指针连接的多个块.
>对于可变大小的记录,将块类型更改为BLOCK_DELETED
>通过将新删除的记录的先前指针指向上次删除的记录来维护所有已删除记录的双链表.然后,最后删除的记录的下一个指针指向新删除的记录.
>对于固定大小的记录,只需将删除标记更改为已删除. (不确定他们是否使用双链表来连接所有已删除的记录和固定大小的记录)
插入
>如果没有未使用的空间(已删除的记录),请将数据附加到文件的末尾
>如果有未使用的空间适合新插入的记录,请在此处写入新记录.
>如果有未使用的空间远远大于新插入的记录,则拆分为两个记录:新记录和已删除记录.
>如果有未使用的空间小于新插入的记录,则在那里写入数据,有溢出指针指向其他块的未匹配数据.
更新
>如果用户使用更长的数据更新现有数据会怎样? MyISAM会将记录标记为已删除并找到适合新数据的位置,或者只是使用溢出指针指向不合适的数据?
再回顾一下这个问题
I want to make sure if I understand it correctly,please correct me if
it is not right.
其他问题
>如果表已被删除并插入很多次,因为记录结构可能充满溢出指针和未使用的空间,它会非常低效吗?
最新的问题
What if users update existed data with longer data? Will MyISAM marked the record as deleted and find place that fits the new data or simply use overflow pointer to point to unfitted data?
根据the Book
第10章:“存储引擎”第196页第7段说
For records with variable length,the format is more complicated. The first byte contains a special code describing the subtype of the record. The meaning of the subsequent bytes varies with each subtype,but the common theme is that there is a sequence of bytes that contains the length of the record,the number of unused bytes in the block,NULL value indicator flags,and possibly a pointer to the continuation of the record if the record did not fit into the prevIoUsly created space and had to be split up. This can happen when one record gets deleted,and a new one to be inserted into its place exceeds the original one is size. You can get the details of the meanings of different codes by studying the switch statement in_mi_get_block_info() in storage/myisam/mi_dynrec.c.
基于该段落,只有当要插入的新数据不适合先前分配的块时,旧记录才会被链接数据覆盖.这可能会导致许多臃肿的行.
其他问题
Would it be very inefficient if the table has been deleted and inserted for many times since the record structure could potentially full of overflow pointers and unused space?
根据我之前的回答,会有很多块
>空间块
>记录的长度
>块中未使用的字节数
> NULL值指示符标志
>如果记录不适合先前创建的空间并且必须拆分,则可能是指向记录延续的指针
这样的记录链接将从插入超大数据的每一行的前面开始.这可能会很快膨胀MyISAM表.MYD文件.
几点建议
MyISAM的默认行格式是动态.当表是动态的并且经历了大量的INSERT,UPDATE和DELETE时,这样的表需要优化
OPTIMIZE TABLE mytable;
还有一种方法:将表的行格式切换为Fixed.这样,所有行都是相同的大小.这就是你如何使行格式固定:
ALTER TABLE mytable ROW_FORMAT=Fixed;
即使使用固定行格式,也必须花费时间来查找可用记录,但时间将是O(1)搜索时间(在外行人的术语中,无论有多少行,都需要相同的时间来查找可用记录该表有或删除了多少行.您可以通过启用concurrent_insert来绕过该步骤,如下所示:
将此添加到my.cnf
[MysqLd]
concurrent_insert = 2
不需要MysqL重启.赶紧跑
MysqL> SET GLOBAL concurrent_insert = 2;
这将导致所有INSERT转到表的后面而不查找可用空间.
固定行表的优点
> INSERT,UPDATE和DELETE会更快一些
> SELECT速度提高20-25%
以下是关于SELECT的一些帖子,其中Row Formats被修复得更快
> 2012年5月3日:Which is faster,InnoDB or MyISAM?
> 2011年9月20日:Best of MyISAM and InnoDB
> 2011年5月10日:What is the performance impact of using CHAR vs VARCHAR on a fixed-size field?
固定行表的缺点
在大多数情况下,当您运行ALTER TABLE mytable ROW_FORMAT = Fixed;时,表可能会增长80-100%. .MYI文件(MyISAM表的索引页)也将以相同的速率增长.
结语
如果你想要MyISAM表的速度并且可以使用更大的表,那么我需要我的替代建议.如果要为每个MyISAM表节省空间,请保留行格式(动态).您将不得不使用OPTIMIZE TABLE mytable压缩表;动态表更频繁.