ORACLE rownum 설명.. 그리고 hint 절을 사용하자.. 게시판 페이지처리
DBMS/ORACLE2009. 10. 20. 18:31
원글 URL : http://greenalice.tistory.com/71
오라클에서 rownum 은 쿼리가 실행될 때 결과 레코드에 번호를 나타내어 주는 필드이다.
물론 table을 만들 때 rownum을 만들어줄 필요는 없다.
어떠한 테이블이라도
select rownum from boardtable의 형태로 쿼리를 날리면 레코드에 번호가 나타내어 주는 것을 볼 수 있을 것이다...
따라서 페이징을 위한 쿼리에서 우리는 rownum이 10 보다 크고 20보다 작은...
이런 식의 조건을 주어.. 원하는 범위의 레코드만 쿼리 할 수 있다..
select rownum from boardtable그래서 위와 같이 쿼라하면 어떨까?
결과가 하나도 않나올 것이다.. 왜냐하면.. 쿼리가 실행되면 where 절 부분이 먼저 실행 될 것이고.. select 를 하기전에는 rownum이 없기 때문이다.
따라서, rownum을 긁어오는 쿼리를 한번 미리 해줄 필요가 잇다..
select * from (select rownum numrow , boardtable.* from boardtable) where numrow > 10 and numrow <= 20order by 절을 사용하지 않는다면 이것만으로 우리는 행복할 수 있다.
select * from (select rownum numrow , boardtable.* from boardtable order by reg_date desc) where numrow > 10 and numrow <= 20결과는 원하는 대로 되지 않음을 볼 수 있다.
이유는 아마도.... order by 가 rownum 값을 만드는데 영향을 못주는 것이라고 생각되는데.. 즉.. order by를 지정한다고 해도.. rownum은 최초의 order by 가 없는 상태로 만들어진다고 추측할 수 있다..
select rownum numrow , boardtable.* from boardtable order by reg_date desc select rownum numrow , boardtable.* from boardtable위의 두 쿼리는 실제로 rownum 값을 똑같이 만들어준다.. 물론 뿌리는 순서는 다르지만..
따라서 원하는대로 정렬을 할려면..
select rownum numrow , aa.* from ( select * from boardtable order by reg_date desc ) aa위의 형태로 쿼리를 바꾸어 줘야 한다.
그런데 또 우리는 범위를 지정해야 하니까..
select rownum numrow , aa.* from ( select * from boardtable order by reg_date desc ) aa where numrow > 10 and numrow <= 20하면 아무것도 안나오는 이유는 이미 설명했고..
select rownum numrow , aa.* from ( select * from boardtable order by reg_date desc ) aa where numrow > 10 and numrow <= 20따라서...
select * from ( select rownum numrow , aa.* from ( select * from boardtable order by reg_date desc ) aa ) where numrow > 10 and numrow <= 20위와 같이 해주면 되겟다..
그런데 좀 복잡하다.. 더구나 검색을 한번... 두번... 세번 을 하니... 데이타 양이 많다면 쿼리실행속도가 느려질 가능성이 있다.. 물론 속도에 가장 큰 영향을 주는 것은 order by 이지만 ... 그래서 index를 만들고 hint 절을 써야할 이유가 생기는 것이다.. 인덱스는 order by 를 하는 필드에 주면 된다.. 따라서.. reg_date 필드에 인덱스를 주면 되고... 그러나 hint 절을 사용하려면 유니크 속성이 있어야 한다... 따라서.. 인덱스를 줄 때 reg_date 필드와 프라이머리 키 필드를 같이 걸어주면 유닉속성을 이용할 수 있다..
create unique index idx_board_reg_date on boardtable (reg_date, idx)인덱스가 생성된다..
select /*+ index_desc(boardtable idx_board_reg_date) */ rownum, tvulist.* from tvulistorder by 없이 rownum이 제대로 긁어지나?
select * from (select /*+ index_desc(tvulist idx_board_reg_date) */ rownum as numrow, boardtable.* from boardtable ) where numrow > 10 and numrow <= 20이제 위와 같이하면... 원하는 범위의 데이타를 가져올 수 있겠다..
만일 인덱스를 사용하지 않앗는데... 데이타가 튀어나오는 시간이 좀 늦는다 싶으면.. 인덱스를 사용하라.. 행복할 것이다..
'DBMS > ORACLE' 카테고리의 다른 글
[ORACLE] DROP TABLE (0) | 2009.11.13 |
---|---|
ORACLE ROWNUM의 동작 원리와 활용 방법 (0) | 2009.10.21 |
Dynamic SQL의 사용 (0) | 2009.10.06 |