포트폴리오 서비스(데이터 추가 느린 문제 해결하기)

·2023년 12월 21일
0

Portfolio Backtest

목록 보기
12/31

생각한 것

  • 지금 저장한 데이터의 양이 매우 적다.
    -> 우선 2023년도의 데이터를 추가해서 사용하자!
  • 포트폴리오는 여러 종목으로 구성된다.
    -> 우선 단일 종목의 기간 수익률을 구하는 것을 구현하자!
  • 가격을 배열로 받아서 수익률을 구하는 함수를 구현하자.

데이터 추가하기

기존에 만든 관리 페이지를 통해서 데이터를 추가할려 했는데 속도가 매우 느렸다. 해당 문제를 수정해 보자!

속도가 느린이유 찾아보기!

  • 우선 데이터 저장 과정을 보자
    API 호출(파일이 있을 경우 파일에서) -> Json 파싱 -> DB 저장
  • DB저장의 경우 / 중복을 체크하고 저장

-> API호출의 경우 거의 발생하지 않고(파일이 이미 존재하기 때문) DB 저장에 문제가 있을거라고 판단했다.

DB 저장에서 중복 확인 삭제

    public StockPrice save(StockPrice stockPrice) {
        if(stockPriceRepository.findByItmsNmAndBasDt(stockPrice.getItmsNm(), stockPrice.getBasDt()) == null) {
            return stockPriceRepository.save(stockPrice);
        }
        return null;
    }

해당 부분에서 if문을 제거하였다. 하지만 속도가 크게 달라지지 않았다. 저장을 하면 할수록 조회하는 쿼리가 많기 때문에 오래걸리는거 같았는데 크게 상관없었다.

문제점

DB를 조금 생각해보면 속도가 느린이유를 알수있다. JPA를 사용하는데 save를 이용한다. save의 경우 1개를 저장할 때 마다, Transaction이 발생한다. 즉, 수 많은 데이터를 저장하기 위해서 적합하지 않은 것이다. DB로 보자면 commit을 계속 실행해서 속도가 느린것이다. saveAll을 이용해야한다.
해당 부분은 추후 다시 공부해야겠다.

saveAll

public List<StockPrice> saveAll(List<StockPrice> stockPrices) {
        return stockPriceRepository.saveAll(stockPrices);
    }

저장할 것을 List로 받아서 저장한다.

    public void loadStockPriceByBaseDate(String baseDate) {
        JsonArray stockJson = dataPortalApi.getStock(baseDate);

        if(stockJson == null){
            return;
        }
        List<StockPrice> stockPrices = new ArrayList<>();

        for(int i = 0 ; i < stockJson.size() ; i++){
            StockPrice stockPrice = new StockPrice();
            stockPrice.setItmsNm(stockJson.get(i).getAsJsonObject().get("itmsNm").getAsString());
            stockPrice.setSrtnCd(stockJson.get(i).getAsJsonObject().get("srtnCd").getAsString());
            stockPrice.setMkp(Long.parseLong(stockJson.get(i).getAsJsonObject().get("mkp").getAsString()));
            stockPrice.setClpr(Long.parseLong(stockJson.get(i).getAsJsonObject().get("clpr").getAsString()));
            stockPrice.setHipr(Long.parseLong(stockJson.get(i).getAsJsonObject().get("hipr").getAsString()));
            stockPrice.setLopr(Long.parseLong(stockJson.get(i).getAsJsonObject().get("lopr").getAsString()));
            stockPrice.setTrqu(Long.parseLong(stockJson.get(i).getAsJsonObject().get("trqu").getAsString()));
            stockPrice.setTrPrc(Long.parseLong(stockJson.get(i).getAsJsonObject().get("trPrc").getAsString()));
            stockPrice.setMrktTotAmt(Long.parseLong(stockJson.get(i).getAsJsonObject().get("mrktTotAmt").getAsString()));
            String basDt = stockJson.get(i).getAsJsonObject().get("basDt").getAsString();
            LocalDate date = LocalDate.parse(basDt, DateTimeFormatter.ofPattern("yyyyMMdd"));
            stockPrice.setBasDt(date);

            stockPrices.add(stockPrice);
        }
        stockPriceService.saveAll(stockPrices);
    }

하루를 기준으로 모든 데이터를 List로 만들어서 saveAll을
호출하였다.
성공적으로 올해 데이터를 저장하였다.

브랜치 종료 및 합치기

지금까지 feature/stock-price-db의 브랜치를 사용하였다. 우선 develop 브랜치에 merge하고 다음작업은 새로운 브랜치에서 시작해보자!

profile
백엔드 개발자가 꿈인 컴공과

0개의 댓글

관련 채용 정보