在我的MySQL数据库中,有一个表有2,000,000条记录。现在,我想在此表中再插入6,000,000条新记录。
为了加快插入速度,我应该使用禁用/启用键,如下所示:
ALTER TABLE cars DISABLE KEYS;
INSERT INTO cars ...
...
...
INSERT INTO cars ...
ALTER TABLE search_all_values ENABLE KEYS;
OPTIMIZE TABLE cars;
但我不知何故觉得,禁用/启用键更适合用于空表插入。
虽然在我的情况下,我已经在表中有2,000,000条记录,当ENABLE KEYS
时,mysql将重新创建所有索引(包括现有记录和新添加的记录),这可能无法产生效率在我的案例中整个数据插入。 重新创建所有索引需要很长时间,OPTIMIZE TABLE
可能也是如此
我想问你的意见我是对的,我怎样才能在我的案例中插入有效的数据?
答案 0 :(得分:48)
您必须根据引擎类型选择您的方法...优化for MyISAM或for InnoDB。
我们最近运行了一个基准,比较了插入数据的不同方式,并测量了从插入前到所有索引完全恢复的时间。它在一张空桌子上,但我们使用了多达1000万行。
带有LOAD DATA INFILE
和ALTER TABLE ... ENABLE/DISABLE KEYS
的MyISAM在我们的测试中获胜(在Windows 7系统上,MySQL 5.5.27 - 现在我们在Linux系统上尝试它)。
ENABLE和DISABLE KEYS不适用于InnoDB,只适用于MyISAM。对于InnoDB,如果您确定数据不包含重复项,请使用SET AUTOCOMMIT = 0; SET FOREIGN_KEY_CHECKS = 0; SET UNIQUE_CHECKS = 0;
(上传完成后不要忘记将它们设置为1
。)
批量插入后我认为你不需要OPTIMIZE TABLE
- MySQL行按插入排序,无论如何都会重建索引。通过批量插入没有“额外碎片”。
如果我犯了实际错误,请随时发表评论。
更新:根据我们最新和最完整的测试结果,对DISABLE / ENABLE键的建议是错误的。
一位同事有一个程序运行多个不同的测试 - 一个预先填充InnoDB / MyISAM的表,空的,选择和插入速度LOAD DATA LOCAL
,INSERT INTO
,REPLACE INTO
和{{1}在“密集”和“碎片化”的表格中(我不太确定如何,我认为它是UPDATE
的固定种子,因此它仍然具有可比性)并且启用了可扩展的索引。
我们在Windows和Linux上测试了许多不同的MySQL版本(5.0.27,5.0.96,5.1.something,5.5.27,5.6.2)(不过两个操作系统上的版本都不一样)。当桌子空着时,MyISAM才赢了。 InnoDB在数据存在时速度更快,并且通常表现更好(除了hdd-space - MyISAM在磁盘上更小)。
尽管如此,要真正从中受益,你必须自己测试 - 使用不同的版本,不同的配置设置和耐心 - 特别是对于奇怪的不一致性(5.0.97比5.5.27快得多)配置 - 我们仍然在寻找原因)。 我们所发现的是 DELETE FROM ... ORDER BY RAND() LIMIT ...
和DISABLE KEYS
旁边没有价值,如果你不是以空表开头,有时会有害。
答案 1 :(得分:1)
索引新密钥需要一些时间。由您来决定是否希望一次完成(首先禁用它)或一次一个(通过保持原样并让它在添加每条记录时进行索引)
我会选择后者,而不是禁用你的钥匙。如果你担心服务器压力太大,你可以尝试分批插入,例如每分钟只有一定数量的插入物。