因此,出于开发目的,我需要一个包含大约100万到1亿个值的表,我目前的方法根本不快。
开发人员通常做了多少行来测试他们的程序可以处理它们的速度?
我当前的方法是有10个for循环,但它对于我需要的行数确实很慢。
那么我该怎样做才能快速插入数百万行?在这种情况下,专业开发人员会做些什么?
答案 0 :(得分:2)
答案 1 :(得分:2)
从您的问题中不清楚您需要插入的数据的性质是什么,但如果可以在最快的方式生成,则可以在一个查询中执行(将插入1m这样的客户)
INSERT INTO customers (id, customer_name)
SELECT n, CONCAT('Customer', n)
FROM
(
select a.N + b.N * 10 + c.N * 100 + d.N * 1000 + e.N * 10000 + f.N * 100000 + 1 N
from (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) a
, (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) b
, (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) c
, (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) d
, (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) e
, (select 0 as N union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) f
) t
这是针对10k行的 SQLFiddle 演示
推荐阅读:
答案 2 :(得分:1)
通常,插入的最慢部分是更新索引。要加速批量插入,请禁用索引,发送插入,然后重新启用它们。
此外,使用多插入语法之一,而不是为每一行发出INSERT
语句。
答案 3 :(得分:1)
我猜您插入的记录如下:
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");
注意:要优化插入速度,请将许多小操作合并为一个大型操作。理想情况下,您进行单个连接,一次发送许多新行的数据,并将所有索引更新和一致性检查延迟到最后。
答案 4 :(得分:1)
最快的解决方案是根本不加载数据,而是从预先填充的数据目录开始。
如果您只是初始化开发/测试数据,那么根本不加载数据。从物理备份启动MySQL的新实例。
您可以使用Percona XtraBackup对任何正在运行的MySQL实例进行物理备份,而不会阻止流量。
然后准备备份,它立即可用作实时数据目录。
然后,您可以设置新的测试实例,只需运行cp
即可复制该数据目录,并启动mysqld实例,并指定--datadir到您的备份副本。
您可以重复此操作,将物理备份复制到您需要的任意数量的开发/测试实例。
第二个选项:不要使用INSERT
,请使用LOAD DATA INFILE
。即使使用预准备语句和多行语法,这也比使用INSERT
快一个数量级。
第三个选项:将批量数据准备为CSV文件,将其移动到MySQL的数据目录中,然后创建一个指向该文件的ENGINE=CSV
表。瞧,你有一张满是数据的桌子。然后使用ALTER TABLE ENGINE=InnoDB
并将其转换为真实的内部表格。