Java 为来自2个不同服务器的N个值高效地选择Top/Max/Avg(任何聚合函数)

Java 为来自2个不同服务器的N个值高效地选择Top/Max/Avg(任何聚合函数),java,sql,performance,postgresql,web-services,Java,Sql,Performance,Postgresql,Web Services,我有两个不同的web服务,它们依次与两个不同的POSTGRES DB进行通信,这两个DB具有完全相同的模式(但数据不同) 这些服务的职责是根据传递的条件触发一组查询并检索结果 现在问题解决了- 我正在开发一个新的服务,它应该累积/聚合这些服务的结果,并将其作为最终结果发送。 激发的查询可以包含group by、having子句、order by和聚合函数 对于这个问题,我能想到的唯一解决方案是,从数据库中获取给定条件下的所有数据(,如果存在限制,事件),然后根据用户的请求在我端执行聚合操作 例如

我有两个不同的web服务,它们依次与两个不同的POSTGRES DB进行通信,这两个DB具有完全相同的模式(但数据不同)

这些服务的职责是根据传递的条件触发一组查询并检索结果

现在问题解决了- 我正在开发一个新的服务,它应该累积/聚合这些服务的结果,并将其作为最终结果发送。 激发的查询可以包含group by、having子句、order by和聚合函数

对于这个问题,我能想到的唯一解决方案是,从数据库中获取给定条件下的所有数据(,如果存在限制,事件),然后根据用户的请求在我端执行聚合操作

例如,发送到我的服务的查询是-

select sum(salary), dept_id 
from employee 
group by dept_id 
order by sum(salary) desc
limit 2;
这意味着我只需要发送来自不同部门的前2名工资总额。现在是最棘手的部分

假设这是输出

From DB1:
sum(salary) | dept_id 
10 | 2
8  | 1
5  | 3


From DB1:
sum(salary) | dept_id 
30 | 3
8  | 1
1  | 2
因此,如果我通过了这两个服务的限制,只得到了前2名,那么输出将是错误的

DB1: Sends (10,2) and (8,1)
DB2: Sends (30,3) and (8,1)
现在,如果我根据部门id(1/2/3)在我的服务中进行总结 综合服务:(30,3)和(16,1)

虽然实际输出应该是,但两个DB的两个值的最大值加在一起

Max(DB1+DB2) - 
dept_id1 - (8 + 8) = 16
dept_id2 - (10 + 1) = 11
dept_id3 - (30 + 5) = 35
所以我的实际输出应该是:(35,3)和(16,1)。

在这个示例中,您可以看到我需要来自两个DB的所有值。在我的服务中执行所需的聚合/筛选条件,然后输出结果

问题在于性能

  • 如果我直接在数据库中启动查询,应用所有过滤器并返回结果大约需要2秒
  • 当我的服务与这些数据库对话时,它将检索它们的所有数据(在从它们的末端进行小计算后,如求和),在我的服务中执行计算。这大约需要20秒。
    • 其中,这些数据库需要15秒才能获得所有聚合数据。我的代码在我的服务端对数据进行排序/筛选/聚合需要5秒钟
  • 问题: 如何在这里提高性能?有没有更好的方法来处理这种情况?有哪种算法或调整可以部分应用以提高性能? 如果您需要关于我如何处理它的任何其他信息,请告诉我。

    注意:我有一些并行线程,它们分别从这些服务中读取数据。因此没有性能问题。
    我有处理这两个服务中的数据的并行流,所以即使这样也不应该成为问题。

    在oracle数据库中使用dblink是我喜欢的方法,谷歌搜索表明PostGreSQL中也有dblink

    使用dblink,您可以将这些表视为在您的模式中。这将帮助您使用UNION子句同时获取两个结果,然后您可以对来自两个表的数据一起执行所需的聚合,就像它们来自同一个表一样

    select SUM(SALARY),ID from(select SALARY,ID from test1@DB_LINK_NAME1 UNION select SALARY,ID from test2@DB_LINK_NAME_2) group by ID order by sum(SALARY) desc;
    

    在oracle数据库中使用dblink是我最喜欢的方法,google搜索表明PostGreSQL中也有dblink

    使用dblink,您可以将这些表视为在您的模式中。这将帮助您使用UNION子句同时获取两个结果,然后您可以对来自两个表的数据一起执行所需的聚合,就像它们来自同一个表一样

    select SUM(SALARY),ID from(select SALARY,ID from test1@DB_LINK_NAME1 UNION select SALARY,ID from test2@DB_LINK_NAME_2) group by ID order by sum(SALARY) desc;
    

    实际上,问题是,我的服务将无法访问终端数据库。我只能连接到inturn将与DB对话并向我发送数据的其他服务。所以我需要一个更好的机制来确保我没有检索到所有的数据。事实上,问题是,我的服务将无法访问终端数据库。我只能连接到inturn将与DB对话并向我发送数据的其他服务。所以我需要一个更好的机制来确保我不会检索到所有的数据。