2016-08-14 58 views
5

我有一个Dashboard视图,它需要来自整个数据库的表的少量数据集。我优化了数据库查询(例如,删除的子查询)。现在有〜20个查询依次执行,并且从数据库中获取不同的数据集。大多数HQL查询包含GROUP BYJOIN子句。使用Spring REST接口,结果返回到前端。Spring数据查询执行优化:在JpaRepository中并行执行Hibernate @Query方法

如何优化自定义查询的执行?我最初的想法是并行运行数据库查询。但我该如何实现这一目标?在做了一些研究之后,我发现了注释@Async,它可以并行运行方法。但是这与Hibernate方法一起工作吗?是否总会为每个用JpaRepository中的@Query注解的方法创建一个新的数据库会话?毕竟,运行数据库查询是否会影响总体执行时间?

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

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

我的项目最初是由jHipster(春季启动,MariaDB的,AngularJS等)产生

回答

6

首先,在并行运行这些SQLS不会影响数据库,只会使页面加载速度更快,这样的设计应该专注于此。

我发布这个答案,假设你已经确保你不能合并这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 - 请记住,Async只是作为一个线程产生任务。由于您要使用JPA,请记住实体管理器不是线程安全的。 DAO类将传播事务。这里是一个可能出现的问题的例子 - http://alexgaddie.blogspot.com/2011/04/spring-3-async-with-hibernate-and.html

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

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

+1

谢谢。不幸的是,我太迟不能给你完整的赏金。 –

3

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