MySQL禁用和启用键

32

我在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也可能需要较长时间。

请问您的意见,我是否正确,并且该如何在我的情况下实现高效的数据插入?


你确定关键更新是瓶颈吗? - abcde123483
1
这是我的担忧,这里有人有同样的担忧:http://forums.mysql.com/read.php?21,68820,68939#msg-68939 - Mellon
无论如何,只要你重新启用它们,这些索引就会被创建。尝试进行批量插入而不是逐行插入,同时进行更新统计信息,看看是否能改善一些情况。 - Rahul
Rahul,你说的“bul插入”和“更新统计信息”是什么意思? - Mellon
1
批量插入,指在一个INSERT语句中插入多行数据。 - Devart
1
在我的情况下,在数据插入后优化表是必要的吗? - Mellon
2个回答

62

根据引擎类型,您一定要选择适合的方法来优化MyISAM引擎InnoDB引擎

我们最近进行了基准测试,比较了不同的数据插入方式,并测量了自插入之前到所有索引完全恢复的时间。这是在一个空表上进行的,但我们使用了多达1000万行。

在我们的测试中,MyISAM与LOAD DATA INFILEALTER TABLE ... ENABLE/DISABLE KEYS赢得了胜利(在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的行是按插入顺序排序的,并且索引会被重建。通过进行批量插入并不会出现“额外的碎片化”。

如果我有错误,请随时评论。

更新:根据我们更近期和完整的测试结果,禁用/启用键的建议是错误的。

一位同事运行了多个不同的测试程序 - 在具有InnoDB / MyISAM预设和空表的情况下,使用LOAD DATA LOCALINSERT INTOREPLACE INTOUPDATE进行选择和插入速度,在“密集”和“碎片化”的表格上进行测试(我不太确定如何进行,我想它是沿着DELETE FROM ... ORDER BY RAND() LIMIT ...进行的,带有一个固定的种子,以便仍然可以进行比较),同时启用和禁用索引。

We tested it with many different MySQL versions (5.0.27, 5.0.96, 5.1.something, 5.5.27, 5.6.2) on Windows and Linux (not the same versions on both OS, though). MyISAM only won when the table was empty. InnoDB was faster when data was present already and generally performed better (except for hdd-space - MyISAM is smaller on disk).
Still, to really benefit from it, you have to test it yourself - with different versions, different configuration settings and a lot of patience - especially regarding weird inconsistencies (5.0.97 was a lot faster than 5.5.27 with the same config - we're still searching the cause). What we did find was that DISABLE KEYS and ENABLE KEYS are next to worthless and sometimes harmfull if you don't start with an empty table.

2
这是一个非常棒的答案。感谢您进行了彻底的研究! - pinkgothic
嗯,很不错的努力,但我会怀疑结论,因为测试结果的巨大变化是否表明这里有很多未知因素? - Pacerier

1

索引新键需要一些时间。由您决定是一次性完成(首先禁用它)还是逐个完成(保持原样并在添加每个记录时进行索引)。

我会选择后者,不禁用您的键。如果您担心过度压力服务器,可以尝试分批插入,例如每分钟仅插入一定数量的记录。


@ mlitn,数据插入后优化表怎么样?这一步必要吗? - Mellon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接