当前位置: 首页 > 面试题库 >

为什么默认情况下禁用休眠批处理/ order_inserts / order_updates?

翁文康
2023-03-14
问题内容

为何默认禁用hibernate批处理/ hibernate.order_updates /
hibernate.order_inserts?启用批量大小为50时有什么缺点吗?与order_updates /
order_inserts参数相同。有没有不启用此功能的用例?使用此功能是否会对性能产生影响?

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


问题答案:

通常将设置batch size为合理的大小order_insertorder_updatestrue可以显着提高性能。

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

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倍。如果您有一些连接池,例如50个连接,则可能有50个这样的大缓冲区。而且,如果您有100个使用批处理的不同语句,则所有此类缓冲区都会对内存产生重大影响。启用批处理大小后,它将成为全局设置-
Hibernate会将其用于所有插入/更新。

但是我发现,在所有项目中,性能的提高对内存的影响更为重要,这就是为什么我将其batchsize=100用作默认值。

使用order_insertsorder_updates我认为默认情况下禁用这些设置,因为这些设置仅在启用批处理时才有意义。取消批处理后,这些排序只是开销。

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

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

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

====编辑2016.05.31 ====

一个词order_insertsorder_udpates属性。可以说我们拥有实体AB并以这种方式持久保存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: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。



 类似资料:
  • 问题内容: 我有一个关于乐观锁定Hibernate的问题。我试图深入了解Hibernate的乐观锁定,但是我有一个疑问。Hibernate使用版本方法(整数或时间戳)来实现乐观锁定。要进行配置,您可以使用@Version批注(或xml配置)并创建一个version属性。另一个选项是使用optimistic- lock =“ all”属性进行配置而不进行版本控制。 我的问题是,如果您没有定义任何版本

  • 我有一个工作,处理项目的大块(1000个)。这些项目被封送到一个JSON有效负载中,并作为一个批处理发布到远程服务(在一个HTTP POST中所有1000个)。有时远程服务陷入困境,连接超时。我为此设置了跳过 如果一个块失败了,批处理重试这个块,但一次一个项目(为了找出是哪个项目导致了失败)但在我的情况下,没有一个项目导致了失败,这是整个块作为块成功或失败的情况,应该作为块重试(事实上,下降到单项

  • 问题内容: 谁能向我解释为什么Hibernate 默认情况下不设置注释,而是允许实体根据当前设置的属性生成INSERT? 什么是不使用的原因,因此默认情况下包括所有实体属性? 问题答案: @ jb-nizet说了什么。 另外,在我的书中是个坏主意。 从生成的SQL跳过空字段,很快您将发现自己处于声明列的情况,这实际上导致持久数据与休眠知道的实体数据不同。这会造成挫败感,并可能使您诉诸昂贵的电话。

  • 问题内容: 我有一个dao,它基本上使用hibernate将记录插入到一​​个表中,该dao用标记为注释,并且我有一个服务,该服务会生成其他一些东西,然后调用我的dao。我的服务也标注了使用。 我叫服务循环。我在dao上的插入内容是否可以批量或一个接一个地工作?我如何确定它们可以批量工作?hibernateTransaction Manager是否管理批处理插入? 我正在使用Oracle DB。

  • 问题内容: 谁能向我解释为什么Hibernate 默认将 Dynamic insert = false 设置为10,这是什么原因? 问题答案: @ jb-nizet说了什么。 另外,在我的书中是个坏主意。 从生成的SQL中跳过空字段,很快您将发现自己处于声明列的情况,这实际上导致持久数据与hibernate知道的实体数据不同。这会造成挫败感,并可能使您诉诸昂贵的电话。 例如假设列 并且您为映射到此

  • 问题内容: 试图了解熊猫某些功能背后的设计原理。 如果我有一个3560行18列的DataFrame,那么 是3560,但是 是18。 也许对于来自R的人来说这很自然;对我来说,感觉不太“ Pythonic”。是否在某处介绍了熊猫的基本设计原理? 问题答案: DataFrame主要是基于列的数据结构。在后台,DataFrame内部的数据存储在块中。大致来说,每个dtype都有一个块。 每列都有一个d