IT'S YU
[Oracle] 오라클 데이터베이스 페이징 처리 본문
SQL은 3가지 실행계획을 거처 실행된다.
SQL 파싱: SQL 구문에 오류가 있는지 실행 대상 객체(테이블, 제약조건, 권한 등)가 존재하는지 검사
SQL최적화: SQL이 실행되는데 필요한 시간을 계산 후 어떤 방식이 좋은지 판단
SQL 실행: 계획을 바탕으로 실행
order by 문제
- 실행계획


저 버튼을 누르면 아래와 같이 실행 계획을 볼 수 있다.
실행계획은 OPERATION 행은 안쪽에서 바깥쪽으로, 나머지 행은 위에서 아래로 진행된 것이다.
order by로 정렬을 할 수 있지만 order by를 사용하면 정렬에 쓰인 행을 기준으로 정렬을 해야해야 하는 경우가 발생하여 그 행을 모두 스캔하고 정렬하므로 굉장히 시간이 오래 걸린다.
그렇다면 어떻게 해야할까?
orderby 보다는 인덱스
인덱스를 사용하면 된다.

테이블을 생성할 때 pk_board라는 primary key를 만들었고, 이는 인덱스를 생성한다. 따라서 우리는 pk_board를 통해 index를 갖고 있는 것이다.
인덱스는 이미 정렬되어 있기 때문에 인덱스를 통해서 정렬을 하면 SORT가 필요없다. 따라서 다른 값을 이용하는 것보다 시간이 적게 걸린다.
- 인덱스와 실제 테이블은 위와 같이 ROWID 라는 값으로 연결 되어 있다.
- ROWID는 각 열의 위치를 값으로 갖고 있기 때문에 인덱스를 통해서 테이블의 데이터에 접근할 수 있다.
- 인덱스를 통해 정렬하기 위해서는 힌트를 알아햐 한다.
- 힌트는 ‘내가 전달한 쿼리를 이렇게 처리해 주세요’ 라는 것을 데이터베이스에 보내는 것이다.
- 힌트는 /*+ 로 시작하고 */로 끝난다.
ex) select /*+index_desc (tbl_board pk_board) */ * from tbl_board;
= tbl_board의 모든 데이터를 pk_board 인덱스를 이용해서 역순으로 가져와주세요
방금의 예처럼 select 문에 힌트를 index를 통해서 주면 훨씬 빠르게 데이터를 가져온다.
참고로 index다음에는 _asc나 _desc가 붙는데 각각 오름차와 내림차 정렬을 의미하며, 그 뒤에 괄호에는 primary key가 들어간다.
rownum
rownum은 데이터를 가져올 때 생기는 고유의 id이다.
처음에 접근하는 것부터 1로 시작해 rownum이 만들어지며 이후 정렬할 때에는 바뀌지 않는다.
rownum은 아래와 같이 가져온 데이터를 특정 조건에 따라 정렬할 때 사용된다.

tbl_board에서 가져온 값들을 rownum이 20 이하만 가져와라 == 선착순 20개만 가져와라
여기에서 한 발 더 나아가 rownum이 10 초과, 20 이하를 가져오라고 아래와 같이 작성하면 아무 데이터도 가져오지 못한다.

그 이유는 whrere rownum >10부터 적용이 되기 때문이다.
rownum은 첫 데이터가 선택이 되면 1의 값을 갖게 되는데 1은 10보다 크지 않으므로 그 데이터는 삭제되고 다시 새로운 값을 가져오는데 그 값은 또 첫번째 값이므로 1의 rownum값을 갖게된다.
따라서 모든 데이터들이 rownum을 1만 가졌다가 삭제되는 과정을 반복하고 결과적으로 아무 데이터도 조건을 만족시키지 못해 출력되지 않는 것이다.
이를 해결하기 위해 괄호를 사용하여 아래처럼 입력해주면 되는데 이렇게 select 문 안 from에 두에 괄호를 통해 순서를 묶는 것을 인라인뷰 라고 한다.

위의 명령은 rownum이 20 이하인 데이터들 즉, 맨 뒤에서 20개의 데이터를 가져와(인덱스를 통해 역순으로 정렬을 하라는 힌트를 주었으므로) rownum을 1부터 20을 배정해주고, 이 중 rownum이 10을 초과하는 것들만 가져오라는 뜻이다.
CH12 오라클 데이터베이스 페이징 처리
SQL은 3가지 실행계획을 거처 실행된다. SQL 파싱: SQL 구문에 오류가 있는지 실행 대상 객체(테...
blog.naver.com
'DB > Oracle' 카테고리의 다른 글
[MySQL] ORDER BY CAST (0) | 2022.05.23 |
---|---|
[Oracle] SYNONYM (시노님)- 동의어 (0) | 2022.05.09 |
[Oracle] - 오라클 힌트(hint) (0) | 2022.05.09 |
[Oracle] DB 커넥션 풀 (0) | 2022.05.04 |
[Oracle] DB 테이블스페이스 (0) | 2022.05.04 |