这几天在做性能优化的项目,发现我修改了hibernate.jdbc.batch_size 为50后,性能提升并不明显。经过仔细分析hibernate源代码,发现hibernate默认给batch_size为15.
看一下hibernate是如何赋值默认15的:
我们写入数据库时,有可能这样写:
@Test
public void insertChineseBook() throws Exception {
....
/**
* 每100次向数据库flush一次
*/
if (i % 100 == 0) {
session.flush();
}
}
....
}
希望每100次向数据库flush一次,但是这里flush的时候,hibernate会每15条往数据库写入一次。
看hibernate的源代码:
org.hibernate.engine.jdbc.batch.internal.BatchingBatch.class
@Override
public void addToBatch() {
try {
currentStatement.addBatch();
}
catch ( SQLException e ) {
LOG.debugf( "SQLException escaped proxy", e );
throw sqlExceptionHelper().convert( e, "could not perform addBatch", currentStatementSql );
}
statementPosition++;
if ( statementPosition >= getKey().getBatchedStatementCount() ) {
batchPosition++;
/*大家注意到了没,hibernate会判断当前的batch里面已经有了多少条待执行的sql(batchPosition 变量),如果待执行的条数等于batchSize(就是hibernate.jdbc.batch_size ),那么执行performExecution */
if ( batchPosition == batchSize ) {
notifyObserversImplicitExecution();
performExecution();
batchPosition = 0;
}
statementPosition = 0;
}
}
performExecution执行的就是:statement.executeBatch(),这个是jdbc原生的语句了。
看一下flush的全过程序列图吧:
(图片有点大,看不清,请使用右键,在新标签中打开图片)