Java 为什么默认情况下禁用hibernate批处理/订单插入/订单更新?
默认情况下禁用hibernate批处理/hibernate.order\u更新/hibernate.order\u插入有什么原因吗?当您启用批量大小为50时,是否存在任何缺点?订单更新/订单插入参数也是如此。是否存在不应启用此功能的用例?使用此功能时是否会影响性能Java 为什么默认情况下禁用hibernate批处理/订单插入/订单更新?,java,hibernate,orm,low-latency,Java,Hibernate,Orm,Low Latency,默认情况下禁用hibernate批处理/hibernate.order\u更新/hibernate.order\u插入有什么原因吗?当您启用批量大小为50时,是否存在任何缺点?订单更新/订单插入参数也是如此。是否存在不应启用此功能的用例?使用此功能时是否会影响性能 我只能看到,当我需要减少查询计数时,这些设置非常有用,这在我的应用程序和数据库服务器之间具有高延迟的云环境中尤为必要。通常将批量大小设置为合理大小和顺序插入,order\u将更新为true可以显著提高性能 在我的所有项目中,我都使用此
我只能看到,当我需要减少查询计数时,这些设置非常有用,这在我的应用程序和数据库服务器之间具有高延迟的云环境中尤为必要。通常将
批量大小设置为合理大小和顺序插入,order\u将更新为true
可以显著提高性能
在我的所有项目中,我都使用此配置作为基础:
hibernate.jdbc.batch_size = 100
hibernate.order_inserts = true
hibernate.order_updates = true
hibernate.jdbc.fetch_size = 400
但是,是-使用批处理时可能会对内存造成影响。但这取决于jdbc驱动程序
例如,Oracle JDBC驱动程序为每个PreparedStatement
创建内部缓冲区,并重用这些缓冲区。如果调用简单的update语句,您可以使用ps.setInt(1,…)
、ps.setString(2,…)
等设置一些参数,Oracle将这些值转换为某些字节表示形式,并存储在与此PreparedStatement
和连接相关的缓冲区中
但是,当您的PreparedStatement
使用大小为100的批处理时,此缓冲区将大100倍。如果您有一些连接池,例如50个连接,那么可能有50个这样大的缓冲区。如果有100个不同的语句使用批处理,那么所有这些缓冲区都会对内存产生重大影响。当您启用批量大小时,它将成为全局设置-Hibernate将在所有插入/更新中使用它
然而,我发现在我所有的项目中,性能提高比内存影响更重要,这就是为什么我使用batchsize=100
作为默认值
对于order\u inserts
,order\u updates
,我认为默认情况下这些设置是禁用的,因为这些设置只有在批处理打开时才有意义。如果设置了批处理,则这些排序只是开销
您可以在Oracle的白皮书中找到更多信息:
在“语句批处理和内存使用”部分中
==编辑2016.05.31====
关于order\u的单词插入
并order\u包含
属性。
假设我们有实体A
,B
,并以这种方式保存6个对象:
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); // ...
上述执行后:
- 这6个对象已生成标识符
- 这6个对象连接到会话(StatefulPersistenceContext:entitiesByKey、entityEntries等。/Hib.v3/)
- 这6个对象按相同顺序添加到ActionQueue:[A1、B1、A2、B2、A3、B3]
现在,考虑2例:
案例1:订单插入=false
在刷新阶段,hibernate执行6个insert语句:
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)
ActionQueue = [A1, A2, A3, B1, B2, B3]
insert into A - (A1, A2, A3)
insert into B - (B1, B2, B3)
案例2:订单插入=true
,允许批处理
现在,在刷新阶段,hibernate执行2个批插入语句:
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)
ActionQueue = [A1, A2, A3, B1, B2, B3]
insert into A - (A1, A2, A3)
insert into B - (B1, B2, B3)
我在Hibernate v3中对此进行了研究,我认为Hibernate v4以同样的方式使用ActionQueue。此处的文档:
表示使用这些属性可能会导致性能损失。我想这就是为什么它们不是默认设置的