一、事务提交成本分析
每次事务提交触发磁盘I/O同步(WAL机制)、日志写入和锁资源释放操作,高频独立提交会产生指数级开销。实验表明:MySQL提交1万次单条插入比单次批量插入慢20倍以上。高频提交还加剧锁竞争与死锁风险,导致事务队列膨胀。
二、核心优化方案
合并事务提交
- 关闭自动提交(
autocommit=0
),单事务内完成批量操作后统一COMMIT
,减少日志刷盘次数。 - 示例代码(Python):
python
# 关闭自动提交,每1000条提交一次 cursor.execute("SET autocommit=0") for i in range(0, len(data), 1000): batch = data[i:i+1000] cursor.executemany("INSERT INTO table VALUES (%s, %s)", batch) connection.commit() # 阶段性提交
- 关闭自动提交(
批量大小动态调整
- 单批次数据量控制在 1000-5000条(避免SQL超1M长度限制)。
- 根据内存与响应延迟动态调整批次规模,如:
- 低内存环境:500条/批次。
- 高并发场景:3000条/批次。
专用批量命令
- MySQL:
LOAD DATA INFILE
(比普通INSERT快10-20倍)。 - PostgreSQL:
COPY
命令直接加载CSV文件。
sql
-- MySQL文件导入示例 LOAD DATA INFILE 'data.csv' INTO TABLE orders FIELDS TERMINATED BY ',';
- MySQL:
三、增强性优化技巧
索引策略调整
- 批量插入前移除非关键索引,完成后再重建,减少B+树维护开销。
sql
ALTER TABLE orders DROP INDEX idx_name; -- 删除索引 -- 执行批量插入... ALTER TABLE orders ADD INDEX idx_name (name); -- 重建索引
有序数据写入
- 按主键/索引顺序插入数据,减少磁盘随机I/O(性能提升30%-50%)。
- 反例:无序写入导致频繁页分裂和索引碎片。
连接参数优化
- JDBC添加
rewriteBatchedStatements=true
参数,合并多条INSERT为单语句。 - 调整
innodb_buffer_pool_size
缓存池大小,容纳更多待写入数据。
- JDBC添加