Oracle index와 ROWNUM, 페이징에 대해서

myminimin·2023년 8월 29일
1

오라클 데이터베이스는 페이지 처리를 위해서 ROWNUM이라는 키워드를 사용해서 데이터에 순번을 붙여준 뒤에 사용을 한다.

(ROWNUM : 실제로 존재하는 데이터가 아닌 출력을 하면서 부여되는 가상의 데이터이다. 도착하는 순위를 매김.)

그렇기 때문에 ROWNUM은 상황에 따라서 그 값이 매번 달라질 수 있다.

  • FULL 이용 시
    뒤죽박죽 섞여있는 전체 테이블을 다 뒤져서 꺼내온 후에 정렬을 한다. 그렇기 때문에 뒤죽박죽인 책들 중에서 가장 처음으로 꺼내온 애가 첫번째가 된다.
select 
/*+ FULL(tbl_board) */
rownum, bno, title 

from tbl_board 
where bno>0
order by bno desc;


  • 반면에 index를 사용해서 정렬(DESC) 을 하게되면 가장 높은 번호가 1번을 차지하게 된다.
select 
/*+ INDEX_DESC(tbl_board pk_board) */ 
rownum, bno, title 

from tbl_board 
where bno>0;

index와 rownum을 결합해서 순위를 매길 수 있다는 것!


왜 순위를 매기는가?

-> 페이지 처리하려고 (1~10은 1page, 11~20은 2page... 이런 식으로 나누기 위해서!)


  • index를 이용하는 정렬
    index는 이미 '정렬이 되어있다'는 점이 중요하다. 그렇기 때문에 데이터를 찾아서 SORT하는 과정이 생략이 된다.

게시판 페이징 처리를 하기 위해서는 'bno의 역순으로 정렬한 결과'를 찾아야 하는데 그 이유는

보통 게시판을 보게되면 가장 최근의 글이 제일 위로 올라오기 때문에 가장 큰 수(1번 글보다 10번 글의 10>1 숫자가 더 크다)가 위로 올라오게 정렬을 해야하는 것이다.


1번 페이지에서 1~10번의 글을 가지고 오고 싶으면 이런 식으로 조회를 할 수 있는데

그렇다면 2번 페이지에서 11~20번의 글을 가지고 오는 것도 이렇게 간단하게 조회를 할 수 있지 않을까? 싶지만 아무런 데이터가 조회가 되지 않는다.

그 이유는 위에서 말했다싶이 ROWNUM은 순번이라서 가장 먼저 들어온 값이 1번이다.

하지만 조건에서 rownum이 10보다 커야한다고 이미 필터링이 되어있기 때문에 가장 먼저 들어온 1번, 2번 ... 들이 모두 무효처리가 되었기 때문에 조회가 되지 않는 것이다.

rownum > 0 으로 조건을 바꾸면 이렇게 20개가 출력이 되는 걸 볼 수 있다. (1,2페이지(1~20)의 데이터를 모두 가지고 옴)

이렇기 때문에 ROWNUM은 반드시 '1'이 포함이 되는 조건으로 만들어 줘야한다는 것이다.


그렇다면 2페이지(11~20) 의 데이터만 가지고 오려면 어떻게 해야할까?

SQL 전체를 하나의 데이터베이스 테이블로 생각을 하면 쉬워진다. ROWNUM이라는 하나의 컬럼이 있는데 그 ROWNUM 컬럼의 값이 10보다 크면 우리가 원하는 값의 범위(11~20)만 가지고 올 수 있게 된다!

위에서 사용했던 SQL문을 '인라인 뷰'(SELECT문 안쪽 FROM에 다시 SELECT문) 처리를 하고 그 밖에 ROWNUM이 10보다 크다는 조건을 넣으면

rownum은 하나의 '키워드'이기 때문에 가짜로 컬럼을 하나 만들어 줘야한다. 위에서는 rno 라고 했다!

이렇게 11~20번의 데이터만 가지고 오게 된다!!!

0개의 댓글