gpt4 book ai didi

java - 多次查询一个巨大的集合。有没有更高效的解决方案?

转载 作者:太空宇宙 更新时间:2023-11-04 09:39:33 24 4
gpt4 key购买 nike

我需要您了解以下代码的性能瓶颈/改进方面的专业知识。

我有一个巨大的 INTEREST_RATES 集合(约 250 万个对象),可以重复遍历并获取和返回拟合条目列表。我当前的解决方案是使用 HSQL 内存数据库:

INTEREST_RATE表结构:

CREATE MEMORY TABLE INTEREST_RATES " +
"(EFFECTIVE_DATE DATE not NULL, "
+ "INTEREST_RATE DOUBLE not NULL, "
+ "INTEREST_RATE_CD INT not NULL, "
+ "INTEREST_RATE_TERM INT not NULL, "
+ "INTEREST_RATE_TERM_MULT VARCHAR(5) not NULL,"
+ "TERM_IN_DAYS DOUBLE not NULL,"
+ "PRIMARY KEY (EFFECTIVE_DATE, INTEREST_RATE_CD, INTEREST_RATE_TERM, INTEREST_RATE_TERM_MULT))"

CREATE INDEX dtidx ON INTEREST_RATES (EFFECTIVE_DATE, INTEREST_RATE_CD)

查询:

SELECT * from INTEREST_RATES where INTEREST_RATE_CD = ? and 
EFFECTIVE_DATE = (SELECT MAX(EFFECTIVE_DATE) from INTEREST_RATES
where INTEREST_RATE_CD = ? AND EFFECTIVE_DATE <= ?)

--> 因此,我尝试获取特定 INTEREST_RATE_CD 的最新可用利率,并给出日期上限。

执行查询的 Java 部分:

PreparedStatement p = con.prepareStatement(sql);
p.setLong(1, intRateCd);
p.setLong(2, intRateCd);
p.setDate(3, someDate);

ResultSet r = p.executeQuery();
return resultSetToList(r);

使用 Futures/多线程的 Java 主循环:

ExecutorService executor  = Executors.newFixedThreadPool(4);
CompletionService<TestResult> completionService = new ExecutorCompletionService<>(executor);
long futureCount = 0;

while(deals.next()) //deals is a ScrollableResults set from Hibernate
{
IDealEntity deal = (IDealEntity) deals.get()[0];

//These tasks contain the INTEREST_RATE query action
QueryTask task = new QueryTask(some params...);
completionService.submit(task);
}

try
{
while(futureCount < dealCount)
{
Future<TestResult> result = completionService.take();
TestResult testResult = result.get();
futureCount++;

testResults.add(testResult);
}

executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
}
catch (Exception ex)
{
ex.printStackTrace();
}

现在,当我尝试提高性能或发现代码中的错误时,我的问题是:

  • 您能想出比 inmem 数据库更快的方法来按照查询逻辑重复获取对象吗?有没有更好/更快/任何数据结构?

到目前为止,HSQL 是我能想到的最快的东西。还尝试了 H2,速度慢了很多。

  • 有趣的是,我使用多线程和 ExecutorService 进行的实验并没有真正改变任何性能方面的变化。

如果我使用 1 大小的线程池或 4 个线程,几乎没有区别...

欢迎任何提示或想法或任何东西!

最佳答案

我不认为内存数据库是解决这个问题的好方法。最重要的是避免全表扫描。在我看来,你的索引是正确的。查看应该是毫秒的真实计时会很有用。

如果这还不够,您可以将整个结构作为嵌套索引集合或哈希表加载到内存中,并使用 java 直接遍历它们。

关于java - 多次查询一个巨大的集合。有没有更高效的解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56127793/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com