多线程直接insert性能可能低于单线程,因锁争抢、连接竞争和事务冲突;优化关键在于协作批量写入,如合理分组(500–800行/批)、显式事务控制、连接池+mutex保护、load data infile配合分片csv及分区表,并用std::atomic保证状态同步。

直接用多线程往数据库里塞数据,不加协调,性能反而可能比单线程还差——锁争抢、连接竞争、事务冲突全会爆发。真正的优化不是“开更多线程”,而是让线程协作起来,把数据库的批量能力真正用起来。
std::thread + MySQL INSERT ... VALUES (...),(...),... 的坑
很多人第一反应是:每个线程自己连一个 MYSQL*,各自拼一批 INSERT 语句发过去。这看似并行,实则埋雷:
- MySQL 默认事务隔离级别下,每个
INSERT语句(即使含多值)仍可能触发行锁或间隙锁,线程间互相等待 - 频繁的小批量
INSERT会让网络往返和解析开销远超实际写入成本 - 如果没显式控制事务,每个语句自动提交,等于每条都在刷日志、刷磁盘,
sync_binlog和innodb_flush_log_at_trx_commit直接拖垮吞吐 -
INSERT ... VALUES (a),(b),(c)虽比单条快,但超过 1000 行后,SQL 解析和内存占用陡增,容易触发max_allowed_packet错误
建议:单个线程内,每次拼 500–800 行为一组;必须显式 BEGIN/COMMIT 包裹;插入前执行 SET autocommit = 0。
为什么 LOAD DATA INFILE 比多线程 INSERT 快 5–20 倍
因为它是 MySQL 原生的批量通道:跳过 SQL 解析、绕过查询缓存、直接走存储引擎接口。但要注意它和 C++ 多线程的配合方式:
- 不能让多个线程同时对同一个文件调用
LOAD DATA INFILE—— 文件锁和表锁会串行化 - 更可行的是:C++ 线程先各自生成分片 CSV(如
data_001.csv,data_002.csv),再由单个管理线程按顺序执行LOAD DATA INFILE 'data_001.csv'等命令 - 若需完全并行,可配合 MySQL 分区表 + 每个线程加载到不同分区(需提前建好分区,且确保数据路由正确)
- 注意路径权限:
LOAD DATA INFILE默认只读取服务端本地文件,客户端生成的 CSV 得先scp或通过LOAD DATA LOCAL INFILE(需服务端开启local_infile)
std::mutex + 预分配连接池的必要性
盲目给每个线程配一个 mysql_real_connect() 连接,很快会撞上 MySQL 的 max_connections 上限,或引发连接认证风暴。正确做法是共享连接,但必须加锁保护:
- 用
std::vector<mysql></mysql>预创建 4–8 个连接(根据 CPU 核数和 IO 能力调整),放入线程安全队列 - 每个工作线程从队列取连接 → 执行批量
INSERT或LOAD→ 归还连接,全程用std::mutex保护队列和连接状态 - 避免在持有连接时做耗时计算(如 JSON 解析、加密),否则连接被长期占用,其他线程干等
- 连接空闲超时(
wait_timeout)会导致MySQL server has gone away,需在归还前用mysql_ping()检测,失效则重连
std::atomic + 内存序控制状态同步的细节
当多个线程协同完成一批插入(比如等全部分片写完才触发后续分析),别用轮询 while(!done),也别依赖普通 bool 变量:
- 普通
bool done = false在另一线程改写后,当前线程可能永远看不到更新(编译器优化 + CPU 缓存未刷新) - 应使用
std::atomic<bool> done{false}</bool>,写端用done.store(true, std::memory_order_release),读端用done.load(std::memory_order_acquire) - 如果只是计数(如“已插入多少行”),用
counter.fetch_add(n, std::memory_order_relaxed)就够了,没必要用最重的seq_cst - 切记:
std::atomic只保证该变量本身操作原子,不保护它指向的数据结构(如std::vector内容)
最易被忽略的一点:批量插入的“快”,本质是把随机 IO 变成顺序 IO、把多次小事务压成一次大事务、把 SQL 解析开销摊薄。多线程只是调度手段,不是银弹——线程数超过磁盘并行能力或连接池上限后,只会增加上下文切换和锁竞争,性能反降。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











