The below code takes long to process records My Db has millions of records
- 1000 records processed
- Time Taken: 32149s
/**
* Saves monthly budget accounts to the database.
*
* @param dto the list of monthly budget accounts to save
* @param branchRepo the repository for branches
* @param costCodesRepo the repository for cost codes
* @param budgetVersionRepo the repository for budget versions
* @param monthlyBudgetAccountsRepo the repository for monthly budget accounts
* @return the number of accounts saved
*/
public int saveMonthlyBudgetAccounts(List<MonthlyBudgetAccountsDTO> dto) {
long startTime = System.currentTimeMillis();
// Fetch required data from database and store in memory for later use
List<Branch> branchList = branchRepo.findAll();
Map<String, Branch> branchMap = branchList.parallelStream()
.collect(Collectors.toMap(b -> b.getSapBranch().toLowerCase(), Function.identity()));
List<CostCodes> costCodesList = costCodesRepo.findAll();
Map<String, CostCodes> costCodesMap = costCodesList.parallelStream()
.collect(Collectors.toMap(c -> c.getCostCodeDescription().toUpperCase().trim(), Function.identity()));
List<BudgetVersion> budgetVersionList = budgetVersionRepo.findAll();
Map<String, BudgetVersion> budgetVersionMap = budgetVersionList.parallelStream()
.collect(Collectors.toMap(b -> b.getBudgetVersion().toLowerCase().trim(), Function.identity()));
int count = 0;
for (MonthlyBudgetAccountsDTO acc : dto) {
MonthlyBudgetAccounts m = new MonthlyBudgetAccounts();
MonthlyBudgetAccountsPK pk = new MonthlyBudgetAccountsPK();
String branch = acc.getId().getBranch().toLowerCase();
String costCode = acc.getId().getCostCode().toUpperCase();
String budgetVersion = acc.getId().getBudgetVersion().toLowerCase();
try {
// Set the branch
Branch branchObj = branchMap.getOrDefault(branch.substring(branch.length() - 4), null);
if (branchObj == null) {
// Handle case where branch is not found
branchObj = branchRepo.findById(900); // Replace with default branch object
}
pk.setBranch(branchObj);
// Set the cost code
CostCodes costCodeObj = costCodesMap.get(costCode.trim());
if (costCodeObj == null) {
// Handle case where cost code is not found
throw new NoSuchElementException("Cost code not found");
}
pk.setCostCode(costCodeObj);
// Set the budget version
BudgetVersion budgetVersionObj = budgetVersionMap.get(budgetVersion.trim());
if (budgetVersionObj == null) {
// Handle case where budget version is not found
throw new NoSuchElementException("Budget version not found");
}
pk.setBudgetVersion(budgetVersionObj);
// Set other fields
pk.setAccount(acc.getId().getAccount());
pk.setFinancialYear(acc.getId().getFinancialYear());
m.setId(pk);
m.setTotal(acc.getTotal());
m.setMarch(acc.getMarch());
m.setApril(acc.getApril());
m.setMay(acc.getMay());
m.setJune(acc.getJune());
m.setJuly(acc.getJuly());
m.setAugust(acc.getAugust());
m.setSeptember(acc.getSeptember());
m.setOctober(acc.getOctober());
m.setNovember(acc.getNovember());
m.setDecember(acc.getDecember());
m.setJanuary(acc.getJanuary());
m.setFebruary(acc.getFebruary());
m.setInsertDate(acc.getInsertDate().trim());
monthlyBudgetAccountsRepo.save(m);
// Clear the DTO to free up memory
dto.set(count, null);
count++;
if (count % 1000 == 0) {
System.out.println(count + " records processed");
long endTime = System.currentTimeMillis();
System.out.println(count + " - Time Taken: " + (endTime - startTime) + "s");
startTime = 0;
}
} catch (NoSuchElementException e) {
// Handle any errors that occur while processing the record
e.printStackTrace();
}
}
return count;
}
- Use parallel streams: Since the code is using streams to collect data from the database, it can benefit from using parallel streams to improve performance. By default, streams are processed sequentially, but parallel streams can divide the workload into multiple threads, which can be executed concurrently.