2011-11-21 23 views
18

在我的MySQL数据库中,有一个包含2,000,000条记录的表。现在,我想在此表中再插入600万条新记录。MySQL禁用和启用密钥

要加快插入,我虽然我应该使用禁用/启用键,如下列:

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

我想问问你的意见对我说的对,我怎么能在我的情况下efficent数据插入?

+0

您确定关键更新是瓶颈吗? – abcde123483

+1

这是我的担心,这里有人有同样的担心http://forums.mysql.com/read.php?21,68820,68939#msg-68939 – Mellon

+0

反正,这些索引将被创建,一旦你再次启用它们。尝试做一个Bul插入而不是行/行,并做一个更新统计,看看是否改善任何东西。 – Rahul

回答

1

索引新密钥需要一些时间。这取决于你是否希望一次完成所有事情(先禁用它)或一次一个(保持原样并让它索引,因为每个记录都被添加)

I' d去追求后者,而不是禁用你的钥匙。如果您担心服务器压力过大,您可以尝试批量插入,例如每分钟只有一定数量的插入。

+0

@ mlitn,如何在数据插入后优化表格,这一步是否有必要? – Mellon

39

你一定要选择你的方法基于引擎类型...优化for MyISAMfor InnoDB

我们最近运行了一个基准测试,比较插入数据的不同方式,并测量插入之前的时间和所有索引完全恢复的时间。它在一张空桌子上,但我们用了多达1000万行。

带有LOAD DATA INFILEALTER 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 LOCALINSERT INTOREPLACE INTOUPDATE,在“密”和“分散”表(我不太确定,我认为这是沿着DELETE FROM ... ORDER BY RAND() LIMIT ...的行,因为它具有固定的种子,因此它仍然具有可比性)以及启用和可撤销的索引。

我们在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快很多同样的配置 - 我们仍然在寻找原因)。 我们发现的DISABLE KEYSENABLE KEYS如果你不是从空表开始的话,它们是毫无价值的,有时甚至是有害的。

+1

这是一个非常奇妙的答案。感谢您的深入研究! – pinkgothic

+0

嗯,很好的努力,但我会怀疑结论,因为测试结果中的巨大变异不会表明这里有很多**未知因素吗? – Pacerier