具有许多索引的 InnoDB 与 MyISAM

Bat*_*707 6 mysql innodb myisam index

我不确定这个问题的答案是对还是错,因为我认为这在很大程度上取决于情况,但为了心理锻炼,我还是继续问吧:

我的数据库中有一个 MyISAM 表,它位于我的站点的中心。围绕它创建了许多参考表,还有许多其他表直接链接到该表中的行 ID。该表大约有 260k 行,有 28 个字段,其中大部分是 varchars 和 ints。我有大约 15 个索引(数据大约 70 MiB,索引大约 80 MiB)。每天可能有数百次写入,而读取数以万计。我的数据库位于 SSD 驱动器上。

现在我的问题是;将此表更改为 InnoDB 表是否有益?我正在努力扩展我的系统以包括 API 流量,这意味着该表甚至会被查询更多,我想确保一切运行尽可能顺利。因此,我有点倾向于将其转换为 InnoDB。但是,由于该表需要许多索引,我认为 MyISAM 可能会更有效地工作。谁能帮我下定决心?提前致谢1

编辑:(由 jcolebrand 从评论中添加)

我很久以前就添加了索引,并且我对 PHP 代码库进行了一些更改,因此可能有些索引已经过时,但总体而言;是的,它们都被使用了。我在表上运行了许多不同类型的查询。不同的查询,不同的索引。但是我在这里的主要问题不涉及表读取性能,而是它如何处理许多索引。InnoDB 索引与数据一起“离开”/存储,而不是 MyISAM 的密钥文件原则。我只是担心这可能会导致足够的性能下降不会超过表锁定问题。

Rol*_*DBA 6

每天可能有数百次写入,而读取数以万计。我的数据库位于 SSD 驱动器上。

基于这个陈述,让我们玩一些数字。假设每天有 500 次写入和 20,000 次读取。这计算出以下

  • 每天阅读 97.56%
  • 每天 2.44% 的写入
  • 40 读/写

尽管我很喜欢 InnoDB,但出于多种原因,在这种情况下我必须选择 MyISAM

原因#1

您只有 150MiB 的 MyISAM 表(70MiB 数据,80 MiB 索引)

原因#2

InnoDB 索引往往会变得非常臃肿,因为二级索引具有进入聚集索引的键。这总是导致双索引查找。对于大型写入量大的数据集,这可能会被忽略。

原因#3

InnoDB 表空间往往会变得非常臃肿,因为 MVCC 在没有自动回收磁盘空间的情况下被创建和丢弃:

所有这些都可以通过 MyISAM 避免

原因#4

InnoDB 通过执行 MVCC 进行事务控制来保护单个行。一天内读取产生的开销可能会超过 150 MiB。

我可能还能说出 2 或 3 个更多原因,但让我们切入正题:在您的情况下,有什么可以提高 MyISAM 的性能的吗?为什么,是的。

你说以下

该表大约有 260k 行,有 28 个字段,其中大部分是 varchars 和 ints

如果您有很多 varchar,则可以采取一些措施来提高读/写性能。对于任何 MyISAM 表mydb.mytable:运行以下命令:

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

这将做什么,这会将所有 VARCHAR 视为 CHAR。每行的长度将完全相同。这将增加 80%-100% 的磁盘空间。在您的情况下,假设它将您的 150 MiB MyISAM 表加倍到 300 MiB。好处在哪里?您的 MyISAM 表现在可以在任何地方读取/写入 20% - 30% 的速度,而无需更改任何其他内容 我从MySQL 数据库设计和调整的第 72,73 页中了解到。

我以前写过关于这个的文章:


归档时间:

查看次数:

7621 次

最近记录:

13 年,4 月 前