为什么默认禁用hibernate batchching / order_inserts / order_updates? [英] Why is hibernate batching / order_inserts / order_updates disabled by default?

查看:1016
本文介绍了为什么默认禁用hibernate batchching / order_inserts / order_updates?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有任何理由为什么hibernate batching / hibernate.order_updates / hibernate.order_inserts在默认情况下是禁用的?启用50的批量大小时是否有任何缺点? order_updates / order_inserts参数相同。是否有一个用例不应该启用此功能?使用这个特性会对性能产生什么影响吗?

我只能看到这些设置有很多帮助,当我需要减少特别是在云中需要的查询计数时我的应用程序和数据库服务器之间的延迟时间很长。

解决方案

通常设置批量大小到合理的大小和 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 使用大小为100的批次时,此缓冲区将会大100倍。如果你有一些连接池用于exapmle 50连接,那么可以有50个这样的大缓冲区。如果使用批处理有100个不同的语句,则所有这些缓冲区都会对内存产生重大影响。当你启用批量大小时,它会变成全局设置 - Hibernate会将其用于所有插入/更新。

然而我发现在我所有的项目中,性能增益更重要,内存的影响,这就是为什么我使用 batchsize = 100 作为我的默认值。



使用 order_inserts order_updates ,我认为这些默认情况下是禁用的,因为这些设置只有在打开批处理时才有意义。随着批量的出发,这些订单只是开销。



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

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



语句批处理和内存使用部分

== ==编辑2016.05.31 ====



关于 order_inserts order_udpates 属性。
可以说我们有实体 A B 并以这种方式保留6个对象:

  session.save(A1); //添加到动作队列
session.save(B1); //添加到动作队列
session.save(A2); // ...
session.save(B2); // ...
session.save(A3); // ...
session.save(B3); // ...

执行上述操作后:


  • 这6个对象具有生成的标识符

  • 这6个对象连接到会话(StatefulPersistenceContext:entitiesByKey,entityEntries等/Hib.v3/) / li>
  • 这6个对象以相同的顺序添加到ActionQueue中:[A1,B1,A2,B2,A3,B3]


现在,考虑两种情况:

情况1: order_inserts = false code>



在冲洗阶段,hibernate会执行 6个插入语句:

<$ (A1)
插入B - (B1)
插入A - (A2)
插入B - (B2)
插入A - (A3)
插入B - (B3)
order_inserts = true ,允许批处理

/ p>

现在,在刷新阶段,hibernate执行 2批处理插入语句:

  ActionQueue = [A1,A2,A3,B1,B2,B3] 
插入A - (A1,A2,A3)
插入B - (B1,B2,B3)

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


are there any reasons why hibernate batching / hibernate.order_updates / hibernate.order_inserts are disabled by default? Is there any disadvantage when you enable a batch size of 50? Same for the order_updates / order_inserts parameters. Is there an use case where you shouldn't enable this features? Are there any performance impacts when using this features?

I can only see that these settings help a lot when i need to reduce my query count which is necessary especially in a cloud environment with high latencies between my application and database server.

解决方案

Generally setting batch size to resonable size and order_insert, order_updates to true can significantly improve performance.

In all my projects I use this configuration as basis:

hibernate.jdbc.batch_size = 100
hibernate.order_inserts   = true 
hibernate.order_updates   = true
hibernate.jdbc.fetch_size = 400

But, yes - there can be memory impact when using batching. But this depends on jdbc driver.

For example Oracle JDBC driver creates internal buffers for each PreparedStatement and reuses these buffers. If you call simple update statement you set some parameters with ps.setInt(1, ...), ps.setString(2, ...) etc, and Oracle converts this values to some byte representation and stores in buffer associated with this PreparedStatement and connection.

However when your PreparedStatement uses batch of size 100, this buffer will be 100 times larger. And if you have some connection pool with for exapmle 50 connections there can be 50 such big buffers. And if you have 100 different statements using batching all such buffers can have significant memory impact. When you enable batch size it becomes global setting - Hibernate will use it for all insert/updates.

However I found that in all my projects performance gain was more important that this memory impact and that is why I use batchsize=100 as my default.

With order_inserts, order_updates, I think that these are disabled by default, because these settings make sense only when batching is on. With batching set off, these ordering is simply overhead.

You can find more info in Oracle's white paper:

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

in section "Statement Batching and Memory Use".

==== EDIT 2016.05.31 ====

A word about order_inserts and order_udpates property. Lets say we have entities A, B and persist 6 objects this way:

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);  // ...

after above execution:

  • these 6 objects has identifiers generated
  • these 6 objects are connected to session (StatefulPersistenceContext: entitiesByKey, entityEntries, etc. /Hib.v3/)
  • these 6 objects are added to ActionQueue in the same order: [A1, B1, A2, B2, A3, B3]

Now, consider 2 cases:

case 1: order_inserts = false

during flush phase hibernate performs 6 insert statements:

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)

case 2: order_inserts = true, batching allowed

now, during flush phase hibernate performs 2 batch insert statements:

ActionQueue = [A1, A2, A3, B1, B2, B3]
insert into A -  (A1, A2, A3)
insert into B -  (B1, B2, B3)

I investigated this for Hibernate v3, I think Hibernate v4 uses ActionQueue in the same way.

这篇关于为什么默认禁用hibernate batchching / order_inserts / order_updates?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆