[꼼꼼한 개발자] 꼼코더

44. 코드로 배우는 스프링 웹 프로젝트 - [페이징 처리] - ROWNUM과 인라인뷰, 인덱스를 이용한 접근 시 ROWNUM 본문

Spring/코드로 배우는 스프링 웹 프로젝트

44. 코드로 배우는 스프링 웹 프로젝트 - [페이징 처리] - ROWNUM과 인라인뷰, 인덱스를 이용한 접근 시 ROWNUM

꼼코더 2023. 1. 28. 22:00
반응형
 

🛼 ROWNUM과 인라인뷰

페이징 처리를 위해 역순으로 게시물의 목록 조회를 성공했다면

이제는 전체가 아닌 필요한 만큼의 데이터를 가져오는 방식을 알아보자

 

ROWNUM이라는 특별한 키워드를 사용하여 데이터에 순번을 붙여 사용해 보자

 

👇🏻 ROWNUM

  • ROWNUM은 SQL 실행결과에 넘버링을 해주는 것이다.
  • 쉽게 말 해 데이터 수집 순위를 매기는 것!(테이블에서 먼저 ACCESS 되는 순으로 매겨짐)
  • 모든 SELECT문에 적용 가능하다
  • 실제데이터가 아니므로 상황에 따라 매번 값이 달라질 수 있다.

👨🏻‍💻 ROWNUM 실습

우선 아무 조건을 적용하지 않고 tbl_board 테이블에 접근하고

각 데이터에 ROWNUM을 적용하면 다음과 같이 작성할 수 있다.

SQL에 아무런 조건이 없으니 데이터는 테이블에 섞여있는 그대로 나오게 된다(FULL 스캔 결과와 동일)

ROWNUM은 테이블에는 존재하지 않고, 테이블에서 가져온 데이터를 이용해서 번호를 매기는 방식으로

위의 결과는 테이블에서 가장 먼저 가져올 수 있는 데이터들을 꺼내어 번호를 붙여주고 있다.

 

이때 번호는 현재 데이터베이스의 상황에 따라 저장된 테이터를 로딩하는 것으로

실습 환경마다 결과는 다르게 나온다.

 

위에 결과 340번 데이터는 3번째로 꺼내진 데이터라고 해석할 수 있다.

만일 테이블에서 데이터를 가져오고 정렬을 하게 되면 340번 ROWNUM 값은 동일하게 3이 된다.

select /*+ FULL(tbl_board) */
rownum rn, bno, title from tbl_board
where bno > 0 order by bno;
 

위에 SQL은 ‘FULL 힌트를 이용하여 전체 데이터를 조회하고 다시 정렬’한 방식이다.

결과를 보면 340번 데이터는 3번째로 접근되었지만

정렬과정에서 뒤쪽으로 밀리는 것을 볼 수 있다.

 

이를 통해서 알 수 있는 사실은 ROWNUM이라는 것은 데이터를 가져올 때 적용되는 것

이후에 정렬되는 과정에서는 ROWNUM이 변경되지 않는다는 것이다.

다른 말로는 정렬은 나중에 처리된다는 의미.


🔑 인덱스를 이용한 접근 시 ROWNUM

ROWNUM에 의미가 테이블에서 데이터를 가져오면 붙는 번호라는 사실을 기억하면

결국 문제는 테이블에 어떤 순서로 접근하는가에 따라 ROWNUM 값은 바뀔 수 있다는 뜻이다.

 

다시 말해, 위의 경우 우선 FULL로 접근해서 320번 데이터를 찾았고

이후에 정렬하는데 이미 데이터는 다 가져온 상태이므로 ROWNUM에는 아무런 영향을 주지 않는다

 

만일 PK_BOARD 인덱스를 통해서 접근한다면 다음과 같은 과정으로 접근한다.

1) PK_BOARD 인덱스를 통해서 테이블에 접근 후

2) 접근한 데이터에 ROWNUM 부여

 

1)의 과정에서 이미 정렬이 되어 있기 때문에

320번의 접근 순서는 3번째가 아니라 한참 뒤일 것이다. (320 언저리.?)

이유는 인덱스의 특징은 이미 정렬이 되어있다는 점.

 

아래의 경우는 ROWNUM은 전혀 다른 값을 가지게 된다.

select /*+ INDEX_ASC(tbl_board pk_board) */
rownum rn, bno, title, content from tbl_board
where bno > 0 order by bno;

 

위의 SQL은 인덱스를 찾는 순서가 다름으로 아래와 같은 방식으로 실행되게 된다

 

힌트를 이용해서 tbl_board 테이블을 pk_board의 순번으로 접근하게 되면 ROWNUM의 값이 305번으로 달라진 것이 보인다. 이때의 실행계획은 다음과 같다

 

만일 게시물의 역순으로 테이블을 접근하게 된다면

320번의 ROWNUM 값은 접근하는 순서가 뒤쪽이기 때문에 큰 값이 나오게 된다.

 

ROWNUM은 데이터에 접근하는 순서이기 때문에

가장 먼저 접근하는 데이터가 1번이 되는데

 

이를 이용하면 테이블을 bno의 역순으로 접근하여

bno값이 가장 큰 데이터가 ROWNUM 값이 1이 되도록 작성할 수 있다.

 

select /*+ INDEX_DESC(tbl_board pk_board) */
rownum rn, bno, title, content from tbl_board
where bno > 0;

 

 

위의 SQL은 PK_BOARD 인덱스를 역으로 타면서

테이블에 접근했기 때문에 bno 값이 가장 높은 데이터를 가장 먼저 가져오게 된다.

 

이 방식을 이용하면 각 게시물을 정렬하면서 순번을 매겨줄 수 있다

1페이지의 경우는 위의 그림에서 RN이라는 칼럼의 값이 1부터 10에 해당한다고 볼 수 있다.

 

 

 

 

 

Comments