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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27755461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:20:26  来源:igfitidea点击:

Why is hibernate batching / order_inserts / order_updates disabled by default?

javahibernateormlow-latency

提问by fbe

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?

是否有任何原因默认禁用 hibernate batching / hibernate.order_updates / hibernate.order_inserts?启用批量大小为 50 时有什么缺点吗?order_updates / order_inserts 参数相同。是否存在不应启用此功能的用例?使用此功能时是否有任何性能影响?

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.

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

回答by przemek hertel

Generally setting batch sizeto resonable size and order_insert, order_updatesto truecan significantly improve performance.

一般设置batch size到合理的大小和order_insertorder_updatestrue能显著提高性能。

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 impactwhen using batching. But this depends on jdbc driver.

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

For example Oracle JDBC driver creates internal buffers for each PreparedStatementand 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 PreparedStatementand connection.

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

However when your PreparedStatementuses 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.

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

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

然而,我发现在我的所有项目中,性能提升比这种内存影响更重要,这就是我将其batchsize=100用作默认值的原因。

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.

对于order_inserts, order_updates,我认为这些默认情况下是禁用的,因为这些设置仅在批处理打开时才有意义。随着批处理开始,这些排序只是开销。

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

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

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

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

in section "Statement Batching and Memory Use".

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

==== EDIT 2016.05.31 ====

==== 编辑 2016.05.31 ====

A word about order_insertsand order_udpatesproperty. Lets say we have entities A, Band persist 6 objects this way:

一个关于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);  // ...

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]
  • 这 6 个对象生成了标识符
  • 这6个对象连接到会话(StatefulPersistenceContext:entitiesByKey、entityEntries等/Hib.v3/)
  • 这6个对象以相同的顺序添加到ActionQueue中:[A1, B1, A2, B2, A3, B3]

Now, consider 2 cases:

现在,考虑两种情况:

case 1:order_inserts = false

情况1:order_inserts = false

during flush phase hibernate performs 6 insertstatements:

在刷新阶段休眠期间执行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)

case 2:order_inserts = true, batching allowed

情况 2:order_inserts = true, 允许批处理

now, during flush phase hibernate performs 2 batch insertstatements:

现在,在刷新阶段休眠执行2 个批量插入语句:

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 v3 对此进行了调查,我认为 Hibernate v4 以相同的方式使用 ActionQueue。

回答by Jason White

The documentation here: https://docs.jboss.org/hibernate/stable/orm/userguide/html_single/chapters/batch/Batching.html

这里的文档:https: //docs.jboss.org/hibernate/stable/orm/userguide/html_single/chapters/batch/Batching.html

says there may be a performance penalty for using these properties. I would assume this is the reason they are not set by default.

说使用这些属性可能会降低性能。我认为这是默认情况下未设置它们的原因。