我有一个大约 300M 行的 MyISAM 格式的表,我想转换为 Innodb
我最初的目标是通过将表模式更改为具有更简单的索引来减少使用量。我转储了所有表,删除了它,用更少的索引重新创建它,现在正在重新导入。但是,我忘记指定它应该是 innodb 而不是 myisam。
我可以只做标准的 ALTER TABLE ... ENGINE=INNODB 吗?这么大的桌子有什么特别需要注意的吗?
数据导入操作大约需要 12 个小时——我不想再这样做了。因此,为什么我只想转换它。
我有一个大约 300M 行的 MyISAM 格式的表,我想转换为 Innodb
我最初的目标是通过将表模式更改为具有更简单的索引来减少使用量。我转储了所有表,删除了它,用更少的索引重新创建它,现在正在重新导入。但是,我忘记指定它应该是 innodb 而不是 myisam。
我可以只做标准的 ALTER TABLE ... ENGINE=INNODB 吗?这么大的桌子有什么特别需要注意的吗?
数据导入操作大约需要 12 个小时——我不想再这样做了。因此,为什么我只想转换它。
以下摘录来自《高性能 MySQL,第二版》一书。
这是一本很棒的书,我会推荐给任何人。
简短的回答是:
根据您的桌子大小和条件,无论您选择哪种方法,我认为您可能需要等待很长时间。
表转换
有几种方法可以将表从一种存储引擎转换为另一种,每种方法都有优点和缺点。
更改表
此语法适用于所有存储引擎,但有一个问题:它可能需要很多时间。MySQL 会将旧表逐行复制到新表中。在此期间,您可能会使用服务器的所有磁盘 I/O 容量,并且在转换运行时原始表将被读锁定。
转储和导入
为了更好地控制转换过程,您可以选择首先使用 mysqldump 实用程序将表转储到文本文件中。转储表后,您可以简单地编辑转储文件以调整其中包含的 CREATE TABLE 语句。确保更改表名及其类型,因为即使它们是不同类型的,同一数据库中也不能有两个同名的表 - 并且 mysqldump 默认在 CREATE TABLE 之前编写 DROP TABLE 命令,因此如果您不小心,您可能会丢失数据!
创建和选择
第三种转换技术是第一种机制的速度和第二种机制的安全性之间的折衷。与其一次性转储整个表或将其全部转换,不如创建新表并使用 MySQL 的 INSERT ... SELECT 语法来填充它,如下所示:
如果您没有太多数据,这很有效,但如果您这样做,增量填充表通常更有效,在每个块之间提交事务,这样撤消日志就不会变得很大。假设 id 是主键,重复运行此查询(每次使用较大的 x 和 y 值),直到将所有数据复制到新表:
完成此操作后,您将留下原始表格,您可以在完成后删除它,以及现在已完全填充的新表格。如果需要,请小心锁定原始表,以防止获得不一致的数据副本!
ALTER TABLE 语句基本上做同样的事情:服务器创建一个临时表,它复制所有行,然后执行重命名。InnoDB 和 MyISAM 之间的磁盘格式非常不同,因此我不希望您找到任何捷径。
另一个评论(您可能知道,但它会帮助其他人阅读此内容):InnoDB 的磁盘格式高度依赖于主键,因为它基于它对记录进行聚类。因此,在使用大型 InnoDB 表时,在选择主键之前要三思而后行,因为更改它会重建整个表,就像手头的问题一样。
无论如何,我建议先在一张中等大小的桌子上做一些测试,然后计时。