Вы нуждаетесь в вашем опыте по узким местам / улучшениям производительности со следующим кодом.
У меня есть огромная коллекция (~ 2,5 миллиона объектов) INTEREST_RATES для многократного обхода, выборки и возврата списков подходящих записей.Мое текущее решение для этого - база данных памяти 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);
Основной цикл Java с использованием Futures / многопоточности :
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 db, для многократного извлечения объектов в соответствии с логикой запроса?Есть ли какая-нибудь лучше / быстрее / какая структура данных?
До сих пор HSQL был самой быстрой вещью, которую я мог придумать.Также попробовал H2, который был намного медленнее.
- Интересно, что мой эксперимент с использованием многопоточности и ExecutorService действительно ничего не меняет в производительности.
Это почти без разницы, еслиЯ использую 1 размер ThreadPool или 4 темы ...
Любые советы или идеи или что-либо приветствуется!