如何让MySQL更快地插入数百万条记录?

23

我想将数百万条记录插入我的数据库,但速度非常缓慢,大约每小时只有40000个记录,我不认为我的硬件太慢,因为我发现磁盘IO速度低于2 MiB/s。 我有许多表格分散在不同的.sql文件中。 一个单一的记录也很简单,一个记录少于15列,一列少于30个字符。我是在使用mysql 5.3的archlinux下完成这项工作的。你们有什么想法吗?或者这个速度不算慢吗?


您应该能够每分钟上传40k行。您如何导入记录? - Daniel W.
1
什么是瓶颈?你是如何插入记录的?你能以某种方式对其进行分析以确定哪个部分需要较长时间吗? - David
你也可以使用预处理语句 - 如果你是通过编程语言进行插入的话。 - alandarev
实际上,我从一个sqlite数据库中转储了所有的表,并保存为.sql文件。我想使用以下命令将这些表导入到mysql服务器:mysql -u user -p database < table_name.sql。这些sql文件看起来像这样: CREATE TABLE T ( ... ); INSERT INTO table1 (field1, field2) VALUES ("data1", "data2"); INSERT INTO table1 (field1, field2) VALUES ("data1", "data2"); ......(数百万行) - Cricket
1个回答

47

很可能是因为您插入记录的方式是这样的:

INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");

每次需要插入数据时都发送新的查询是性能不佳的。相反地,将这些查询合并成单个查询,像这样。

发送新的查询来插入数据会使性能下降,建议将这些操作合并成单个查询。

INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2"),
                                                 ("data1", "data2"),
                                                 ("data1", "data2"),
                                                 ("data1", "data2"),
                                                 ("data1", "data2");
您还可以在MySQL文档中了解有关插入速度的更多信息。它明确描述如下。
为优化插入速度,请将许多小操作合并为单个大操作。理想情况下,您只需建立一次连接,一次性发送许多新行的数据,并延迟所有索引更新和一致性检查,直到最后。
当然,如果数量非常大,请不要全部合并。比如您需要插入1000行数据,就不应该一次性插入。相反,将其分成较小的大小进行插入。
如果仍然非常慢,那可能是因为您的服务器太慢了。
请注意,当然您不需要在组合查询中使用所有这些空格,这只是为了更好地概述答案。

2
我尝试使用单个查询插入约50000行数据,但出现了SQL查询太大的错误。 - Josef
1
@Josef,每当超过x行时,请创建一个新的查询。 - vallentin
13
这个答案非常有帮助。逐步插入的步骤花了我接近6个小时才完成1.5M条记录的插入,但是使用这种方法,每组10000条记录一次,只需要大约90秒 :D - Kimutai
9
如果您能从文本文件中导入数据,使用LOAD DATA INFILE。MySQL手册指出,这通常比使用INSERT语句快20倍。 - sobstel
也许看起来很合乎逻辑,但如果插入的数据是外部的(用户、第三方公司),并且查询必须受到 SQL 注入的保护呢? - Marek R
显示剩余4条评论

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