为什么默认情况下禁用hibernate batching/order_inserts/order_updates?

fbe*_*fbe 11 java orm hibernate low-latency

hibernate batching/hibernate.order_updates/hibernate.order_inserts默认是否被禁用?批量大小为50时是否有任何缺点?对于order_updates/order_inserts参数也是如此.是否存在不应启用此功能的用例?使用此功能时是否会对性能产生影响?

我只能看到这些设置在我需要减少查询计数时有很大帮助,尤其是在我的应用程序和数据库服务器之间具有高延迟的云环境中.

prz*_*tel 30

通常设置batch size为合理的尺寸order_insert,order_updatestrue显着提高性能.

在我的所有项目中,我使用此配置作为基础:

hibernate.jdbc.batch_size = 100
hibernate.order_inserts   = true 
hibernate.order_updates   = true
hibernate.jdbc.fetch_size = 400
Run Code Online (Sandbox Code Playgroud)

但是,是的 - 使用批处理时可能会对内存产生影响.但这取决于jdbc驱动程序.

例如,Oracle JDBC驱动程序为每个驱动程序创建内部缓冲区PreparedStatement并重用这些缓冲区.如果调用简单更新语句ps.setInt(1, ...),则使用ps.setString(2, ...)等设置一些参数,Oracle将此值转换为某个字节表示形式,并存储在与此PreparedStatement连接关联的缓冲区中.

但是,当您PreparedStatement使用100的批次时,此缓冲区将大100倍.如果你有一些连接池与exapmle 50连接,可以有50个这样的大缓冲区.如果使用批处理有100个不同的语句,则所有这些缓冲区都会对内存产生重大影响.当您启用批量大小时,它将变为全局设置 - Hibernate将使用它进行所有插入/更新.

但是我发现在我的所有项目中,性能提升对于这种内存影响更为重要,这就是我batchsize=100用作默认值的原因.

使用order_inserts,, order_updates我认为这些默认情况下是禁用的,因为这些设置仅在批量处理时才有意义.随着批处理的启动,这些排序只是开销.

您可以在Oracle的白皮书中找到更多信息:

http://www.oracle.com/technetwork/topics/memory.pdf

"语句批处理和内存使用"一节中.

====编辑2016.05.31 ====

关于order_insertsorder_udpates财产的一个词.假设我们有实体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);  // ...
Run Code Online (Sandbox Code Playgroud)

执行完毕后:

  • 这6个对象生成了标识符
  • 这6个对象连接到会话(StatefulPersistenceContext:entitiesByKey,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)
Run Code Online (Sandbox Code Playgroud)

案例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)
Run Code Online (Sandbox Code Playgroud)

我对Hibernate v3进行了调查,我认为Hibernate v4以同样的方式使用ActionQueue.