MySQL插入查询优化

Viv*_*iya 5 php mysql database performance

将大量行插入表中时,以下两种方法中哪一种会更快。

查询方法一:逐条执行查询。

INSERT INTO tbl_user(id, name, number) VALUES(NULL, 'A', '9999999999');
INSERT INTO tbl_user(id, name, number) VALUES(NULL, 'B', '9999999999');
INSERT INTO tbl_user(id, name, number) VALUES(NULL, 'C', '9999999999');
Run Code Online (Sandbox Code Playgroud)

查询方法2:立即执行查询。

INSERT INTO tbl_user(id, name, number) VALUES(NULL, 'A', '9999999999'),
                                             (NULL, 'B', '9999999999'), 
                                             (NULL, 'C', '9999999999');
Run Code Online (Sandbox Code Playgroud)

e4c*_*4c5 6

由于存在一些争论,我想我应该尝试一个基准测试,但首先

 CREATE TABLE `tbl_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `number` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB 
Run Code Online (Sandbox Code Playgroud)

然后,我使用 2 行 python 生成问题中形式的 SQL 查询。

场景 1:
许多单个插入,每个插入的查询完全相同

INSERT INTO tbl_user VALUES(NULL,'A','9999999');
INSERT INTO tbl_user VALUES(NULL,'A','9999999');
Run Code Online (Sandbox Code Playgroud)

1000 行;三次执行的平均(mean)运行时间 45.80 秒
5000 Rows;单次运行220秒

场景2:
单个查询插入1000行,如下所示:

INSERT INTO tbl_user VALUES(NULL,'A','9999999'),
(NULL,'A','9999999'),
(NULL,'A','9999999'),
(NULL,'A','9999999'),
Run Code Online (Sandbox Code Playgroud)

1000 行 3 次执行的平均运行时间 0.17 秒
5000 行 3 次执行的平均运行时间 0.48
10000 行 3 次执行的平均运行时间 1.06

场景 3:
与场景 1 类似,但使用 aSTART TRANSACTIONCOMMIT包裹插入语句

1000 行 3 次执行的平均运行时间 0.16 秒
5000 行 3 次执行的平均运行时间 0.48
10000 行 3 次执行的平均运行时间 0.91

结论:
方案 2(其他两个答案中提出的方案)确实在很大程度上优于方案 1。有了这些数据,很难在 2 和 3 之间做出选择。需要对更多插入件进行更严格的测试。但如果没有这些信息,我可能会选择三个,原因是解析一个非常大的字符串通常会产生开销,准备一个字符串也是如此!我怀疑如果我们尝试在一条语句中一次插入大约 50,000 条记录,实际上可能会慢很多。

  • 完美的答案和适当的例子。 (2认同)