在mysql的日常开发中,经常需要一次性向表中写入多条数据,比如批量导入用户数据、批量新增订单记录等场景。如果使用单条insert语句逐行插入,每一次插入都会产生一次客户端与数据库的交互,还会触发多次事务提交和日志写入,整体效率很低。而使用insert into的多值语法,可以将多条插入语句合并为一次操作,大幅减少交互次数和资源消耗。

insert into多值语法基础用法
insert into多值语法的标准格式是在values关键字后跟上多组用括号包裹的值,每组值对应一行插入数据,组与组之间用英文逗号分隔,具体语法如下:
-- 假设存在用户表user,结构为id int自增, name varchar(50), age int
INSERT INTO user (name, age)
VALUES
('张三', 20),
('李四', 22),
('王五', 25);
上述语句执行后,会一次性向user表中插入3条用户记录,只需要一次数据库交互即可完成,比执行3次单条insert语句效率高很多。
单条插入与多值批量插入性能对比
我们可以通过简单的测试来对比两种插入方式的性能差异,测试环境为本地mysql8.0,插入1000条随机用户数据:
单条插入实现
-- 单条插入1000次,这里用存储过程模拟
DELIMITER //
CREATE PROCEDURE insert_single()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i < 1000 DO
INSERT INTO user (name, age) VALUES (CONCAT('user_', i), FLOOR(RAND()*50)+10);
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
CALL insert_single();
多值批量插入实现
-- 多值批量插入1000条,这里用存储过程拼接语句模拟
DELIMITER //
CREATE PROCEDURE insert_batch()
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE sql_str TEXT DEFAULT 'INSERT INTO user (name, age) VALUES ';
WHILE i < 1000 DO
IF i = 0 THEN
SET sql_str = CONCAT(sql_str, CONCAT('('user_', i, '', ', FLOOR(RAND()*50)+10, ')'));
ELSE
SET sql_str = CONCAT(sql_str, CONCAT(',('user_', i, '', ', FLOOR(RAND()*50)+10, ')'));
END IF;
SET i = i + 1;
END WHILE;
SET @sql = sql_str;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
CALL insert_batch();
实际测试中,单条插入1000条数据耗时约1.2秒,而多值批量插入仅耗时约0.1秒,性能提升超过10倍。随着插入数据量的增加,两者的性能差距会更加明显。
批量插入的注意事项
- 单次批量插入的数据量不宜过大,mysql对单条sql语句的长度有默认限制,由
max_allowed_packet参数控制,如果插入数据量超过该限制,语句会执行失败,建议单次批量插入控制在1000到2000条以内,超量数据可以分批次插入。 - 如果表存在自增主键,多值插入时自增主键会按照插入顺序依次分配,和单条插入的自增逻辑一致,不会出现主键冲突问题。
- 如果插入的数据中包含重复的唯一索引值,多值插入会因为唯一索引冲突导致整批插入失败,如果需要忽略冲突,可以在insert后添加
IGNORE关键字,冲突的行会被跳过,正常行会插入成功。 - 批量插入时如果开启事务,所有插入操作会在事务提交时一次性写入,相比自动提交模式效率更高,建议在批量插入前手动开启事务,插入完成后提交。
常见场景示例
比如需要批量插入商品数据,商品表product结构为id int自增, product_name varchar(100), price decimal(10,2), stock int,批量插入5条商品记录的语句如下:
INSERT INTO product (product_name, price, stock)
VALUES
('笔记本电脑', 4999.00, 100),
('无线鼠标', 89.90, 500),
('机械键盘', 299.00, 300),
('显示器', 1299.00, 200),
('USB扩展坞', 129.00, 400);
如果需要忽略重复的商品名称(假设product_name有唯一索引),可以添加IGNORE关键字:
INSERT IGNORE INTO product (product_name, price, stock)
VALUES
('笔记本电脑', 4999.00, 100),
('无线鼠标', 89.90, 500);
mysqlinsert_into批量插入多值语法性能优化修改时间:2026-06-23 07:15:31