java - 为什么默认禁用 hibernate batching/order_inserts/order_updates?

标签 java hibernate orm low-latency

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

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

最佳答案

通常将batch size设置为合理的大小,并将order_insertorder_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 倍。如果您有一些连接池,例如 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个对象连接到 session (StatefulPersistenceContext:entitiesByKey,entityEntries等/Hib.v3/)
  • 这 6 个对象以相同的顺序添加到 ActionQueue:[A1, B1, A2, B2, A3, B3]

现在,考虑两种情况:

案例 1:order_inserts = 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)

情况 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。

关于java - 为什么默认禁用 hibernate batching/order_inserts/order_updates?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27755461/

相关文章:

java - 什么更快?获取空记录或检查是否存在?

java - 当循环继续执行时删除随机生成的字符串

java - jpa2 hibernate,一个测试实体锁定的测试用例

hibernate - 在 nHibernate 中使用 CreateCriteria 向连接添加限制

php - 使用 Laravel 的 Eloquent 将数据发送到数据库的问题

java - 如何替换我正在搜索的单词

java - 字符串队列到单个字符串

Hibernate:多对多连接表的标准?

java - jOOQ MySQL 如何确定复杂的 DELETE 是否影响行

hibernate - 为什么我的多级继承映射没有像我期望的那样工作?