Board 프로젝트에서 게시글의 댓글을 출력하는 부분에서 엄청 많은 댓글 데이터가 존재한다면, 많은 양을 가져와야 하는만큼 시간과 성능의 문제를 가져온다. 내가 추구하는 좋은 사용자 경험을 만족 시키지 못한다!
사실 이 부분에 대해서는 과거 부트캠프에서 진행했던 프로젝트를 회고하면서 다음에는 그렇게 안해야지! 했던 부분이라서 한번 적용시켜보기로 했다.
대용량의 데이터를 가져올 때 성능적인 부분의 효율을 높이려면 여러가지 방법이 있지만, 그 중에서도 인덱싱과 페이징을 적용해보려고 한다.
댓글이 사용되는 방식은 게시물 번호를 통해서 사용된다. 예를 들어, 게시물 당 댓글의 수를 조회하거나, 해당 게시물의 댓글 목록을 보는 등의 경우가 있다. (참고: ManyToOne)
그러니까 이건 '댓글 테이블 where bno = 번호 order by rno desc' 식으로 조회가 된다.
1. 인덱싱
여기서 bno = 101을 조회하려고 한다면,
인덱스가 없다면? 정렬을 통해 하나하나 맞는 번호를 찾아야 하는데, 조회할 때마다 정렬을 해야하므로 매우매우 비효율적이다.
이걸 인덱스를 활용하면 데이터를 빠르게 조회할 수 있다.
bno에 대한 인덱스를 생성하면 bno를 키로 사용해서 데이터를 미리 정렬한 인덱스 테이블이 생성된다. (보통 B-tree)
101을 조회할 때 인덱스를 통해 정렬없이 해당 101 bno를 가진 위치를 빠르게 찾을 수 있다.
+ 인덱스는 메모리에 적재되어 있기 때문에 디스크에서 필요한 데이터를 더 적은 양으로 가져올 수 있다.
@Table
나는 @Table을 사용하였다.
@Entity
@Table(name = "Reply", indexes = {
@Index(name = "idx_reply_board_bno", columnList = "board_bno")
})
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString(exclude = "board")
public class Reply extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long rno;
@ManyToOne(fetch = FetchType.LAZY)
private Board board;
private String replyText;
private String replyer;
}
- @Table : 엔티티 클래스가 매핑되는 데이터베이스 테이블의 정보 지정
- name: 데이터베이스 테이블의 이름 지정(기본적으로 엔티티 클래스의 이름이 데이터베이스 테이블의 이름으로 사용됨)
- catalog: 데이터베이스의 카탈로그 지정
- schema: 데이터베이스의 스키마 지정
- uniqueConstraints: 유니크 제약 조건 지정
Reply 테이블에 매핑시켰고, 'idx_reply_board_bno'라는 이름의 인덱스를 생성하였다. 그리고 이 인덱스의 키 칼럼은 board_bno이다.
2. 페이징
페이징 처리는 한번에 모든 데이터를 가져오는 대신 페이지 단위로 데이터를 가져올 수 있기 때문에 성능을 향상시킨다. 그리고 시간 또한 줄어들으므로 사용자 경험이 향상될 수 있다!
@Query
그래서 특정 게시글의 댓글을 페이징 처리 할 수 있도록 @Query를 통해 Pageable 기능을 작성하였다.
public interface ReplyRepository extends JpaRepository<Reply, Long> {
@Query("select r from Reply r where r.board.bno = :bno")
Page<Reply> listOfBoard(Long bno, Pageable pageable);
}
listOfBoard () : 게시글 번호(bno) 를 기준으로 해당 글에 속하는 댓글을 페이징해서 조회하는 기능을 제공
JPQL쿼리를 작성해서 게시글 번호에 해당하는 댓글을 조회하는 @Query를 작성
'Tech > Spring | Spring Boot' 카테고리의 다른 글
[Spring DB] 트랜잭션 AOP 주의 사항 - 프록시 내부 호출 (0) | 2024.04.13 |
---|---|
[Lombok] @Cleanup, @All/NoArgsConstructor, @RequiredArgsConstructor (0) | 2024.04.12 |
[Spring Boot] Querydsl 을 이용한 동적 쿼리 처리 하기 (0) | 2024.04.09 |
[Servlet] 리스너(Listener)에 대해 살짝 알아보기 (0) | 2024.04.05 |
[Spring Boot] PRG(POST-Redirect-GET) 패턴 ? 그게 뭐냐면 (1) | 2024.03.24 |
댓글