批量执行insert时,有多种执行方式:
1 循环单条执行,类似:
for(){
insert(sql);
}
2 合并为一个事务执行(注:Mysql默认事务是自动提交的,需关闭事务自动提交),类似:
事务begin
for()
{
insert(sql);
}
事务commit
3 采用insert...values value1,value2批量执行,类似:
insert into table_name values (value1),(value2)...(valueN);
下表是在单机情况下,通过java api调用mysql接口方式执行10,100,500,1000条记录insert时的性能表格
记录数 |
多次循环执行(1) |
通过一个事务执行(2) |
insert合并(3) |
10 |
366ms |
28ms |
25ms |
100 |
2509ms |
49ms |
26ms |
500 |
6419ms |
83ms |
34ms |
1000 |
26591ms |
241ms |
75ms |
备注:
1 数据表大小未超过innodb_buffer_pool_size。
2 单条记录为308个字节,max_allow_packet设置为16M。
3 innodb_flush_log_at_trx_commit=1,单机无binlog。
4 测试中的执行时间只是一个相对值,不同机器表现肯定不一样。
结论:
1 从实测情况可以知道,在3 的情况下,批量insert性能最高。
2 java api里面的addBatch是1的情形。
造成性能差距的可能原因:
1和2,(1) 1在执行每一条insert时,mysql都会启动一个事务来跟踪;而2减少了mysql的事务数。
(2)减少了事务日志的同步次数。
1和3,(1) 压缩了网络通信次数,(2) 减少了sql解析次数,(3) 减少了事务数和日志同步次数。
2和3,减少了sql解析次数。