批量插入性能远超单条INSERT,关键在于合理划分事务边界、禁用约束检查、使用LOAD DATA INFILE、规避自增主键热点、优化连接池配置,并优先排查锁与日志刷盘瓶颈。
INSERT 快得多,但要注意事务边界单条 INSERT INTO t VALUES (1),(2) 和 1000 条 INSERT 语句在高并发下性能差距可达 10 倍以上。关键不是“能不能用批量”,而是“在哪切分事务”。
MySQL 的 autocommit=1 默认开启,每条 INSERT 都触发一次刷盘(innodb_flush_log_at_trx_commit=1 时),这是最大瓶颈。
INSERT INTO t VALUES (1),(2),(3),...,(1000) 替代循环执行 1000 次单值 INSERT
BEGIN; INSERT ... ; INSERT ... ; COMMIT;,把 100–1000 行包在一个事务里(太大易锁表、回滚开销高)innodb_log_file_size 和 innodb_buffer_pool_size,避免频繁 checkpointSET unique_checks=0; SET foreign_key_checks=0;,完成后恢复LOAD DATA INFILE 是最快写入方式,但权限和路径限制多比等量 INSERT 快 5–20 倍,本质是绕过 SQL 解析层,直接走存储引擎接口。但它要求数据文件在 MySQL 服务端本地(或启用了 local_infile=ON 并配合客户端 --local-infile),且用户需有 FILE 权限。
FIELDS TERMINATED BY ',')、行结束符(LINES TERMINATED BY '\n')、空值表示(NULL 或 \N)都要匹配REPLACE 或 IGNORE,它们会触发行锁或唯一键扫描;如需去重,先写临时表再 INSERT ... SELECT ... ON DUPLICATE KEY UPDATE
split -l 100000 data.csv chunk_,再逐个 LOAD DATA INFILE '/path/chunk_aa'
ANALYZE TABLE t,更新统计信息,避免后续查询执行计划劣化InnoDB 的聚簇索引让主键成为写入热点。若所有连接都往同一数据页末尾插入(比如 AUTO_INCREMENT 主键),会产生 LOCK_MODE_X 行锁竞争,甚至 adaptive hash index 锁等待。
innodb_autoinc_lock_mode=2(交错模式),允许并发获取自增值(需 binlog_format=ROW)REPLACE INTO 或 INSERT ... ON DUPLICATE KEY UPDATE 在高频写入场景滥用——它们先查后写,容易锁住唯一索引项UUID_SHORT() 或雪花 ID(应用层生成)替代 AUTO_INCREMENT,但注意 UUID 无序性会导致二级索引碎片,需定期 OPTIMIZE TABLE
innodb_change_buffering=inserts(默认已开),延迟合并非唯一二级索引变更,降低随机 IO哪怕 SQL 和参数全调优了,如果

Creating sort index 或 Waiting for table metadata lock。
maxActive / maxPoolSize 不应盲目设高;建议按实际并发请求数 × 1.5 设(如 QPS 200,平均响应 100ms,则活跃连接约 20)wait_timeout 和 interactive_timeout(建议 300 秒),防止空闲连接长期占着不放SHOW PROCESSLIST 查看是否有大量 Sleep 状态连接;用 performance_schema.events_statements_summary_by_digest 找出慢写入的 SQL 模板真正卡住高并发写的,往往不是磁盘或 CPU,而是锁等待、日志刷盘节奏、或者连接没被复用。调参前先看 SHOW ENGINE INNODB STATUS\G 里的 SEMAPHORES 和 TRANSACTIONS 部分,比盲目改 innodb_buffer_pool_size 有用得多。