6.6. 性能调优


6.6.1. 备用批处理算法

Hibernate 允许您使用以下四种获取策略之一为关联加载数据: join、Select、subselect 和 batch。在这四种策略中,批处理加载允许最大的性能提升,因为它是选择获取的优化策略。在此策略中,Hibernate 通过指定主或外键列表,在单个 SELECT 语句中检索一组实体实例或集合。批处理获取是对 lazy 选择获取策略的优化。

有两种方法可以配置批处理获取:每个类级别或每收集级别。

  • 按类级别

    当 Hibernate 在每个类级别上加载数据时,它需要批量大小的关联,以便在查询时预加载。例如,请考虑在运行时您有 30 个加载到会话中的 car 对象实例。每个 car 对象属于一个 所有者 对象。如果您要迭代所有 汽车 对象并请求其所有者,通过加载 lazy,Hibernate 将发出 30 个选择声明 - 每个所有者一个。这是性能瓶颈。

    您可以在通过查询请求之前,告诉 Hibernate 预加载下一批所有者的数据。查询了 所有者 对象后,Hibernate 将在同一个 SELECT 语句中查询更多这些对象。

    提前要查询 的所有者 对象数量取决于配置时指定的 batch-size 参数:

    <class name="owner" batch-size="10"></class>
    Copy to Clipboard Toggle word wrap

    这会让 Hibernate 查询至少 10 个 所有者 对象,预计在不久的将来会需要它们。当用户查询 A 车 的所有者 时,汽车 B 的所有者 可能已经作为批处理加载的一部分加载。当用户实际需要 car B 的所有者,而不是前往数据库(并发出 SELECT 语句)时,可以从当前会话检索该值。

    除了 batch-size 参数外,Hibernate 4.2.0 还引进了新的配置项,以提高批处理加载性能。配置项称为 Batch Fetch Style 配置,由 hibernate.batch_fetch_style 参数指定。

    支持三种不同的批处理获取方式:inrigacY、PADDED 和 DYNAMIC。要指定要使用的样式,请使用 org.hibernate.cfg.AvailableSettings#BATCH_FETCH_STYLE

    • 强制要求:在旧式加载中,使用一组基于 ArrayHelper.getBatchSizes(int) 预先构建的批处理大小。使用现有可批处理标识符数的下一个小型预构建批处理大小来加载批处理。

      继续前面的示例,批处理大小设置为 30,预先构建的批处理大小为 [30、15、10、9、8、7、. 1]。尝试批量加载 29 个标识符将导致批处理 15、10 和 4。将会有 3 个对应的 SQL 查询,每个查询都从数据库中加载 15、10 和 4 所有者。

    • PADDED - 添加类似于udACY 批处理加载样式。它仍然使用预先构建的批处理大小,但使用下一个bigger 批处理大小,并固定额外的标识符占位符。

      与上例所示,如果初始化 30 个所有者对象,则仅对数据库执行一项查询。

      但是,如果要初始化 29 个所有者对象,Hibernate 仍将仅执行一个批处理大小为 30 的 SQL 选择声明,使用带有重复标识符添加的额外空间 padded。

    • 动态 - 虽然符合批处理大小限制,但这种批处理加载的方式使用要加载的实际对象数量动态构建其 SQL SELECT 语句。

      例如,对于 30 所有者对象,最大批处理大小为 30,检索 30 所有者对象的调用将产生一个 SQL SELECT 语句。调用来检索 35 将产生两个分别批处理大小为 30 和 5 的 SQL 语句。Hibernate 将动态更改第二个 SQL 语句,使其保持为 5(所需数量),同时仍保持为批处理大小限制为 30。这与 PADDED 版本不同,因为第二个 SQL 不会获得 PADDED,与 criACY 样式不同,第二个 SQL 语句没有固定大小 - 第二个 SQL 是动态创建的。

      对于少于 30 个标识符的查询,这种样式只会动态加载请求的标识符数。

  • 按收集级别

    Hibernate 还可以按照上述每个类部分中列出的批处理获取大小和样式进行批处理加载集合。

    要反转上一节中使用的示例,请考虑您需要加载每个 所有者 对象拥有的所有 对象。如果在当前会话迭代过程中加载 10 个 所有者 对象,则迭代所有所有者将生成 10 个 SELECT 语句,每个调用 getCars() 方法一个。如果在 Owner 映射中为行车集合启用批量获取,Hibernate 可以预先获取这些集合,如下所示:

    <class name="Owner"><set name="cars" batch-size="5"></set></class>
    Copy to Clipboard Toggle word wrap

    因此,由于批量大小为 5 个,并且使用传统的批处理样式来加载 10 个集合,Hibernate 将执行两个 SELECT 语句,各自检索五个集合。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat