为何默认禁用hibernate批处理/ hibernate.order_updates / hibernate.order_inserts?启用批量大小为50时有什么缺点吗?与order_updates / order_inserts参数相同。有没有不启用此功能的用例?使用此功能是否会对性能产生影响?
我只能看到这些设置在需要减少查询数量时很有用,这在应用程序和数据库服务器之间的延迟很高的云环境中尤其必要。
通常将设置batch size为合理的大小order_insert,order_updates以true可以显着提高性能。
batch size
order_insert
order_updates
true
在我所有的项目中,我都使用以下配置作为基础:
hibernate.jdbc.batch_size = 100 hibernate.order_inserts = true hibernate.order_updates = true hibernate.jdbc.fetch_size = 400
但是, 是的 - 使用批处理可能会 影响内存 。但这取决于jdbc驱动程序。
例如,Oracle JDBC驱动程序为每个缓冲区创建内部缓冲区PreparedStatement并重用这些缓冲区。如果调用简单更新语句,则使用ps.setInt(1, ...),ps.setString(2, ...)等设置一些参数,并且Oracle将此值转换为某些字节表示形式,并存储在与此PreparedStatement和连接关联的缓冲区中。
PreparedStatement
ps.setInt(1, ...)
ps.setString(2, ...)
但是,当您PreparedStatement使用大小为100的批次时,此缓冲区将大100倍。如果您有一些连接池,例如50个连接,则可能有50个这样的大缓冲区。而且,如果您有100个使用批处理的不同语句,则所有此类缓冲区都会对内存产生重大影响。启用批处理大小后,它将成为全局设置- Hibernate会将其用于所有插入/更新。
但是我发现,在所有项目中,性能的提高对内存的影响更为重要,这就是为什么我将其batchsize=100用作默认值。
batchsize=100
使用order_inserts,order_updates我认为默认情况下禁用这些设置,因为这些设置仅在启用批处理时才有意义。取消批处理后,这些排序只是开销。
order_inserts
您可以在Oracle白皮书中找到更多信息:
http://www.oracle.com/technetwork/topics/memory.pdf
在 “语句批处理和内存使用”部分中 。
====编辑2016.05.31 ====
一个词order_inserts和order_udpates属性。可以说我们拥有实体A,B并以这种方式持久保存6个对象:
order_udpates
A
B
session.save(A1); // added to action queue session.save(B1); // added to action queue session.save(A2); // ... session.save(B2); // ... session.save(A3); // ... session.save(B3); // ...
经过以上执行:
现在,考虑2种情况:
情况1: order_inserts = false
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允许批处理
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。