测试快速插入100W条数据

表结构

CREATE TABLE `test_kk` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

几种方式

任何情况下,单条循环插入效率都是极低的,所以就不详细描述了。

存储过程拼接字符串插入

delimiter $$
create PROCEDURE pro1()
BEGIN
	DECLARE i int;
	set i=1;
	set @strsql='INSERT INTO test_kk (name) values ';
	while i>=1 && i<=10000 DO
		IF i=10000 then
			set @strsql=CONCAT(@strsql,'(',i,');');
		ELSE
			set @strsql=CONCAT(@strsql,'(',i,'),');
		end if;
		set i=i+1;
	end while;
	PREPARE stmt FROM @strsql;
	EXECUTE stmt;
	DEALLOCATE PREPARE stmt;
END$$
delimiter ;

call pro1();

在测试之前,我认为这种方式速度是最快的,由于不确定100W条到底需要多久,先尝试了1W条。
执行时间:0.2s

显然,速度非常快,照这个速度来说,一百万条大概是20s左右。
将上面的数字调整为100W,悲剧来了。没有记录具体的时间,大概过了一万年(1900s)左右,执行完毕,我枯了。
然后我又将数字调整为10W,执行时间是15.57s,于是我又尝试将数字调整为1000,执行时间是0.01s。
如此看来,sql拼接字符串越多,时间呈指数型增长。
什么原因,没有深入探究。
另外也尝试了一次循环100W次插入的存储过程,执行时间:2916.67s,看来是可以不用考虑。

如此看来,将数字设为1000,使用代码调用循环调用1000次,执行时间:10.41s,这样是最快的。

代码拼接字符串插入

$sql = 'insert into test_kk (name) values ';
for ($i=1; $i <= 1000000; $i++) {
  $sql .= $i == 1000000 ? '('.$i.');' : '('.$i.'),';
}
$res = DB::select($sql);

100W条数据。
执行时间:2.65s。
我惊了。
PHP不愧是世界上最好的语言。
然后尝试拼接1000W条,结果内存不足,作罢。

以上仅供参考,插入速度和很多东西相关,比如硬盘速度,CPU等硬件水平,插入数据的复杂度,不能一概而论。

然而写测试数据用什么方法,心中似乎有了点B数。