대용량 데이터 저장

Jake·2023년 4월 23일
0

대용량 DB

목록 보기
2/4
post-thumbnail

많은 양의 데이터를 저장할 때 놓친 부분이 있다.

먼저 시간복잡도에 대한 얘기를 해보겠다.

올바른 예시가 아닐 수 있지만 시간 복잡도 측면에서 어떤것을 더 중요히 고려해야 할까?가 갑자기 떠올랐다.

image

정답은 실행시간이다.

왜냐하면 실행시간은 데이터의 수에 영향을 많이 받기 때문이다.

여기서 중요한 부분이 나온다.

데이터가 많으면 많을수록 매번 데이터를 저장하는데 드는 Cost가 누적되며 기하급수적으로 증가한다.

테스트를 진행하며 데이터 저장속도가 왜이리 느린가 생각해보니

아래 코드로 매번 데이터를 생성 저장할때마다 repository에 save()메소드를 호출하는 매우 비효율적인 코드를 사용하여 진행하였다는 것이다.

@Test
    void makeData() throws SQLException {
        for (int i = 1000000; i <= 1500000; i++) {
            Long id = (long) i;
            String content = "내용 없음";

            String s1 = "2022-01-01 00:00:00.000";
            String s2 = "2022-12-31 23:59:59.000";
            Timestamp tp1 = Timestamp.valueOf(s1);
            Timestamp tp2 = Timestamp.valueOf(s2);

            //save
            Post post = new Post(id, content, 10, tp1, tp2);
            this.postRepository.save(post);
        }

첫번째 해결방법은 아주 간단하게도 List 자료구조에 저장한 뒤 그 List를 다시 repository에 저장하는 것이다.

public void saveAll(List<Post> postList) throws SQLException {
        String sql = "insert into post (id, content, likes, createdDate, modifiedDAte) values (?, ?, ?, ?, ?)";

        Connection con = null;
        PreparedStatement pstmt = null; // injection 공격을 예방하기 위해 바인딩 방식 사용

        try {
            con = getConnection();
            pstmt = con.prepareStatement(sql);

            for (Post post: postList) {
                pstmt.setLong(1, post.getId());
                pstmt.setString(2, post.getContent());
                pstmt.setInt(3, post.getLikes());
                pstmt.setTimestamp(4, post.getCreatedDate());
                pstmt.setTimestamp(5, post.getModifiedDate());
                pstmt.addBatch();
            }
            pstmt.executeBatch();

        } catch (SQLException e) {
            log.error("db error", e);
            throw e;
        } finally { // 커넥션을 닫아줘야함
            close(con, pstmt, null);
        }
    }

이 방법을 사용하게 되면 saveAll() 메소드딱 1번만 호출되게 된다.

이 부분만으로 매우 큰 시간복잡도 차이를 보일 것으로 예상된다.

50만건 데이터 기준 기존 25분 -> ??

코드를 실행해본 결과 JVM 메모리 이슈로 50만건의 객체를 리스트에 넣을 경우 stacktrace Error가 발생하였다.

이 에러에 대한 대응은 다음 장에서 다루겠다.

0개의 댓글

관련 채용 정보