为什么会有这么大的差异?
因为这些单独的 INSERT 语句(来自脚本)中的每一个都必须发送到数据库,在那里必须对其进行解析(检查语法和语义......关键字和标识符位于适当的位置,标识符是有效的,用户有对象的权限,... 然后 MySQL 必须制定一个执行计划(实际执行操作的可执行代码,对于插入它非常简单,但仍然必须完成),然后 MySQL 必须执行操作(找到要修改的数据和索引块,获取必要的锁,进行所需的块更改,检查索引违规,触发触发器等,然后将块更改写入二进制/复制日志(二进制日志记录或语句日志记录),以及然后提交更改、释放锁、清理资源并将状态返回给调用者。如果这是从远程机器上运行的,那么通过网络往返于数据库的那些往返会增加时间。
因此,每个语句都有开销。对于单个语句来说,它并不是很大,但对于很多语句来说,它开始快速加起来(或慢慢加起来)。
MySQL 对单个 INSERT 语句的工作要少得多。
这就是为什么我们尽可能避免在循环 RBAR(Row By Agonizing Row)中处理单个行的原因。
MySQL有一个优化可以加快INSERT,在同一个语句中插入多行...
INSERT INTO mytable (mycol1, mycol2) VALUES ('a','a'),('b','b'),('c','c')
但是,在你对行数大发雷霆之前,SQL 语句的最大大小是有限制的。我相信字节数受限于max_allowed_packet
. (请注意,限制是字节,而不是字符,以防万一您使用的是 UTF-8 并且某些字符需要两个或更多字节。)
要在 MySQL 中生成 70,000 行,而不需要脚本,您可以执行以下操作:
INSERT INTO mytable (first_name, last_name)
SELECT CONCAT('test',i.i) AS first_name
, CONCAT('test',i.i) AS last_name
FROM ( SELECT 1 + ten_thousands.digit*10000
+ thousands.digit*1000
+ hundreds.digit*100
+ tens.digit*10
+ ones.digit
AS i
FROM ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
) ten_thousands
CROSS
JOIN ( SELECT 0 AS digit 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
) thousands
CROSS
JOIN ( SELECT 0 AS digit 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
) hundreds
CROSS
JOIN ( SELECT 0 AS digit 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
) tens
CROSS
JOIN ( SELECT 0 AS digit 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
) ones
ORDER
BY ten_thousands.digit
, thousands.digit
, hundreds.digit
, tens.digit
, ones.digit
) i