Spring Data Query执行优化:JpaRepository中Hibernate@Query方法的并行执行

Posted

技术标签:

【中文标题】Spring Data Query执行优化:JpaRepository中Hibernate@Query方法的并行执行【英文标题】:Spring Data Query Execution Optimization: Parallel Execution of Hibernate @Query Method in JpaRepository 【发布时间】:2016-12-20 18:30:48 【问题描述】:

我有一个仪表板视图,它需要来自整个数据库表的一小组数据。我优化了数据库查询(例如删除了子查询)。现在有大约 20 个查询一个接一个地执行,它们从数据库中获取不同的数据集。大多数 HQL 查询包含 GROUP BYJOIN 子句。使用 Spring REST 接口,将结果返回到前端。

如何优化自定义查询的执行?我最初的想法是并行运行数据库查询。但是我该如何实现呢?在做了一些研究之后,我发现了注释@Async,这使得并行运行方法成为可能。但这适用于 Hibernate 方法吗?是否总是为 JpaRepository 中使用 @Query 注释的每个方法创建一个新的数据库会话?运行数据库查询到底对整体执行时间有影响吗?

并行运行数据库调用的另一种方法是将 Dashboard 调用拆分为几个单独的 Ajax 调用(每个关注点都有自己的 Ajax 调用)。我不想这样做,因为每次打开仪表板(或例如更改日期范围)时,都会进行另外 20 次 Ajax 调用以获取新数据。同样的问题仍然存在:并行运行 SQL 查询是否会影响数据库的执行时间?

我目前还没有向数据库添加额外的索引。这将是下一件事,我肯定会这样做。但是,我对并行运行查询的性能影响以及如何使用 Spring 以编程方式实现这一点感兴趣。

我的项目最初是由 jHipster 生成的(Spring Boot、MariaDB、AngularJS 等)

【问题讨论】:

【参考方案1】:

通常并行执行查询会快得多。如果您使用 Spring 数据并且未配置任何特定的 JPA 提供程序(Hibernate)将创建一个连接池来存储与您的数据库的连接。我认为默认情况下 Hibernate 拥有 10 个连接,并且通过这样做它准备并行执行 10 个查询。并行运行查询的速度取决于数据库和表/查询的结构。 我认为使用 @Async 不是这里的最佳做法。定义 20 个提供特定查询结果的 REST 端点是一种更好的方法。通过这样做,您可以为每个查询简单地创建实体、存储库和 RestEndpoint 类。通过这样做,每个查询都是独立的,代码也不会那么复杂。

【讨论】:

【参考方案2】:

首先,并行运行这些 SQL 不会影响数据库,只会使页面加载更快,因此设计应重点关注这一点。

我发布这个答案是假设您已经确定不能组合这 20 个 SQL,因为数据是不相关的(没有连接、视图等)。

出于两个原因,我建议不要使用 @Async。

原因 1 - 当您想触发一堆任务而忘记时,或者当您知道所有任务何时完成时,异步任务非常有用。因此,您需要“等待”所有异步任务完成。你应该等多久?直到最慢的查询完成?

查看此异步示例代码(来自指南@spring.io --https://spring.io/guides/gs/async-method/)

// Wait until they are all done
while (!(page1.isDone() && page2.isDone() && page3.isDone())) 
     Thread.sleep(10); //10-millisecond pause between each check

您的服务组件会/应该等待 20 个异步 DAO 查询吗?

原因 2 - 请记住,异步只是将任务作为线程生成。由于您将使用 JPA,请记住实体管理器不是线程安全的。 DAO 类将传播事务。这是一个可能出现的问题示例 - http://alexgaddie.blogspot.com/2011/04/spring-3-async-with-hibernate-and.html

恕我直言,最好继续进行多个 Ajax 调用,因为这将使您的组件具有凝聚力。是的,您将有 20 个端点,但它们将具有更简单的 DAO、更简单的 SQL、易于单元测试,并且返回的数据结构将更容易被 AngularJS 小部件处理/解析。当 UI 触发所有 20 个 Ajax 调用时,仪表板将在它们准备好时加载单个小部件,而不是同时加载所有小部件。这将通过优化仪表板的较慢加载部分(可能是缓存、索引等)来帮助您在未来扩展您的设计。

捆绑您的 DAO 调用只会使数据结构变得复杂,单元测试更加困难。

【讨论】:

以上是关于Spring Data Query执行优化:JpaRepository中Hibernate@Query方法的并行执行的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data Query执行优化:JpaRepository中Hibernate@Query方法的并行执行

spring-data-jpa @Query 支持正则表达式语法吗?

无法使用 Spring Data JPA 执行聚合函数并获取结果

Spring Data JPA native query 分页

spring data jpa @query的用法

spring jpa 自带page @Query 出错