0

最近,我发现其中一台服务器的磁盘 I/O 流量很高。由于某些诊断后在某些表上写入索引而导致的高 I/O。我做了几次评估测试,发现mysql在向具有大索引的表中插入记录时会占用大量写入。

索引列的数据类型是 varchar(15) 和 varchar(17) ,两者都是非唯一索引,如果我将 20000 条记录加载到具有 10000 条记录的表中,则磁盘上只有 80 次写入,而磁盘上有 1700 次写入时即使插入的记录数相同,表也会增长到 2000 万(在索引列上有大约 100 万个不同的值)。

引擎是 MyISAM。

增加索引的大小也会增加每次插入磁盘上的写入次数。

它是 BTREE 索引行为吗?我该如何解决这个问题?

4

1 回答 1

3

使用 InnoDB 而不是 MyISAM。

InnoDB 通过缓冲对二级索引的写入、尽可能合并它们以及延迟昂贵的 I/O 来提供帮助。您可以在 MySQL 手册中的Controlling InnoDB Change Buffering下阅读有关此功能的更多信息。


回复您的评论:

将新值插入 B 树可能会很昂贵。如果叶级别没有空间,则插入可能会导致拆分树的非叶节点的级联效应,可能一直到树的顶部。这可能会导致大量 I/O,因为树的不同节点可能彼此相距很远地存储在磁盘上。

其他缓解策略是通过将使用较少的数据移动到另一个表来缩小表。或者通过使用MySQL 表分区来使一张逻辑表由许多单独的物理表组成。每个这样的子表必须具有相同的索引,但是每个单独的索引会更小。


这里有一个动画示例:http: //www.bluerwhite.org/btree/

查看示例“将键 33 插入 B-Tree (w/Split)”,其中显示了将值插入过度填充的 B-tree 节点的步骤,以及 B-tree 的响应操作。

现在想象一下,示例插图只显示了更深的 B-tree 的底部(如果您的索引 B-tree 有数百万个条目,就会出现这种情况),并且填充父节点本身可能是溢出,并且强制分裂操作继续向上树中的更高级别。如果到树顶部的所有祖先节点都已被填充,则这可以一直持续到树的最顶部。

于 2013-04-12T02:10:18.340 回答