通常将设置
batch size为合理的大小
order_insert,
order_updates以
true可以显着提高性能。
在我所有的项目中,我都使用以下配置作为基础:
hibernate.jdbc.batch_size = 100hibernate.order_inserts = true hibernate.order_updates = truehibernate.jdbc.fetch_size = 400
但是, 是的 - 使用批处理可能会 影响内存 。但这取决于jdbc驱动程序。
例如,Oracle
JDBC驱动程序为每个缓冲区创建内部缓冲区
PreparedStatement并重用这些缓冲区。如果调用简单更新语句,则使用
ps.setInt(1,...),
ps.setString(2,...)等设置一些参数,并且Oracle将此值转换为某些字节表示形式,并存储在与此
PreparedStatement和连接关联的缓冲区中。
但是,当您
PreparedStatement使用大小为100的批次时,此缓冲区将大100倍。如果您有一些连接池,例如50个连接,则可能有50个这样的大缓冲区。而且,如果您有100个使用批处理的不同语句,则所有此类缓冲区都会对内存产生重大影响。启用批处理大小后,它将成为全局设置-
Hibernate会将其用于所有插入/更新。
但是我发现,在所有项目中,性能的提高对内存的影响更为重要,这就是为什么我将其
batchsize=100用作默认值。
使用
order_inserts,
order_updates我认为默认情况下禁用这些设置,因为这些设置仅在启用批处理时才有意义。取消批处理后,这些排序只是开销。
您可以在Oracle白皮书中找到更多信息:
http://www.oracle.com/technetwork/topics/memory.pdf
在 “语句批处理和内存使用”部分中 。
====编辑2016.05.31 ====
一个词
order_inserts和
order_udpates属性。可以说我们拥有实体
A,
B并以这种方式持久保存6个对象:
session.save(A1); // added to action queuesession.save(B1); // added to action queuesession.save(A2); // ...session.save(B2); // ...session.save(A3); // ...session.save(B3); // ...
经过以上执行:
- 这6个对象已生成标识符
- 这6个对象连接到会话(StatefulPersistenceContext:entityByKey,entityEntries等。/Hib.v3/)
- 将这6个对象以相同的顺序添加到ActionQueue中:[A1,B1,A2,B2,A3,B3]
现在,考虑2种情况:
情况1:
order_inserts = false
在刷新阶段,hibernate执行 6条插入 语句:
ActionQueue = [A1, B1, A2, B2, A3, B3]insert into A - (A1)insert into B - (B1)insert into A - (A2)insert into B - (B2)insert into A - (A3)insert into B - (B3)
情况2:
order_inserts = true允许批处理
现在,在刷新阶段,hibernate执行 2个批处理插入 语句:
ActionQueue = [A1, A2, A3, B1, B2, B3]insert into A - (A1, A2, A3)insert into B - (B1, B2, B3)
我针对Hibernate v3进行了调查,我认为Hibernate v4以相同的方式使用ActionQueue。



