6. 댓글의 페이징 처리 ▷ 현재까지 작성된 예제는 해당 게시물의 전체 댓글을 가져와서 화면에 출력했을 때 문제는 댓글의 숫자가 많을 경우
▷댓글의 숫자가 많다면 데이터베이스에서 많은 양의 데이터를 가져와야하고, 이는 성능상의 문제를 가져올 수 있음
▷ 이런 문제를 페이징 처리를 이용해서 처리함
(1) 데이터베이스의 인덱스 설계 ▷ 댓글에 대해서 우선적으로 고려해야하는 일은 tbl_reply 테이블을 접근할 때 댓글의 번호(rno)가 중심이 아니라 게시물의 번호(bno)가 중심이 된다는 점임 ▷댓글을 조회할 때에는 해당 게시물의 댓글을 가져오기 때문에 'tbl_reply where bno = 200 order by rno asc'와 같은 방식으로 접근함
▷ tbl_reply 테이블의 PK는 rno 이므로 위와 같은 방식으로 쿼리를 실행하면 테이블을 접근하는 방식은 아래와 같음
▷ bno 값이 100번인 게시물의 댓글은 PK_REPLY를 이용해 검색하므로 중간에 다른 게시물 번호들을 건너 뛰어 특정 게시물의 댓글을 찾아야함, 데이터가 많아진다면 성능에 문제가 생길 수 있음
▷효율을 높이려면 번호에 맞게 댓글들을 모아서 빠르게 찾을 수 있는 구조로 만드는 것이 좋음
▷ 아래의 그림은 bno 별로 댓글들을 모았고 특정 게시물의 댓글을 찾을 때 모여 있는 부분만 찾을 수 있음
▷ 위와 같은 구조를 이용하게 되면 'bno=200 order by rno asc'와 같은 쿼리를 실행 할 때 왼쪽 구조에서 200에 해당하는 범위만 찾아서 사용하게 됨
▷이러한 구조를 생성하는 것을 인덱스 생성이라고 하고 SQL은 아래와 같습니다.
create index idx_reply on tbl_reply (bno desc, rno asc);
(2) 인덱스를 이용한 페이징 쿼리
▷ 인덱스를 이용하는 이유 중 하나는 정렬을 피할 수 있기 때문임
특정한 게시물의 rno의 순번대로 데이터를 조회하려면 다음과 같은 쿼리를 작성하게 됨
select /*+INDEX(tbl_reply idx_reply) */
rownum rn, bno, rno, reply, replyer, replyDate, updatedate
from tbl_reply
where bno = 3145745 --(게시물 번호)
and rno > 0
▷ SQL의 실행 계획은 다음과 같이 처리됨
▷ 실행된 결과를 보면 IDX_REPLY를 이용해서 테이블에 접근하는 것을 볼 수 있고 ROWNUM은 가장 낮은 rno 값을 가지는 데이터가 1번이 되게 된다.
▷ROWNUM이 원하는 순서대로 나오기 때문에 페이징 처리는 이전에 게시물 페이징과 동일한 형태로 작성할 수 있음
예) 10개씩 2페이지를 가져온다면 아래와 같은 쿼리를 작성하게 된다.
select rno, bno, reply, replyer, replydate, updatedate
from
(
select /*+INDEX(tbl_reply idx_reply) */
rownum rn, bno, rno, reply, replyer, replyDate, updatedate
from tbl_reply
where bno = 게시물번호
and rno > 0
and rownum <= 20
) where rn > 10
;
◎ ReplyMapper.xml 내용 수정
... (생략) ...
<select id="getListWithPaging"
resultType="org.codehows.domain.ReplyVO">
<![CDATA[
select rno, bno, reply, replyer, replyDate, updatedate
from
(
select /*+INDEX(tbl_reply idx_reply) */
rownum rn, rno, bno, reply, replyer, replyDate, updatedate
from tbl_reply
where bno = #{bno}
and rno > 0
and rownum <= #{cri.pageNum} * #{cri.amount}
) where rn > (#{cri.pageNum} -1) * #{cri.amount}
]]>
</select>
... (생략) ...