지난 시간에는 ROWID의 이용에 대해 살펴봤다. 이 글에서는 ROWID는 다양한 곳에 사용할 수 있는 분량 관계상 소개하지 못한 ROWID의 또 다른 활용 방안을 소개한다.
ROWID를 이용한 조인 방식은 사용자가 직접 변경할 수도 있다. <리스트 1>을 살펴보자.
SELECT A.COL1, B.COL2 FROM TAB1 A, TAB2 B WHERE A.KEY1 BETWEEN B.KEY2 AND B.KEY3;
<리스트 1>의 TAB1 테이블과 TAB2 테이블은 조인을 이용해 데이터를 추출한다. 조인 조건이 ‘=’이 아닌 BETWEEN 조건을 사용하고 있는데, 이 경우 조인 방식 중 중첩 루프 조인만 사용 가능하다. 해당 SQL에 대해 해시 조인을 이용해야 한다면 <리스트 2>처럼 SQL을 변경해야 한다.
SELECT A.COL1, B.COL2 FROM TAB1 A, TAB2 B WHERE A.KEY1 BETWEEN B.KEY2 AND B.KEY3 AND LENGTH(A.ROWID) = LENGTH(B.ROWID);
해시 조인은 ‘=’ 조인에서만 적용 가능하다. 그러므로 TAB1과 TAB2 테이블 모두에 ROWID가 존재하며, ROWID는 길이가 동일하므로 <리스트 2>처럼 SQL을 변경하면 동일한 결과가 추출된다. ROWID를 활용하면 해시 조인을 적용 가능한 것이다.
조인 방식으로는 다음과 같이 세 가지 방식이 있다.
각각의 조인 방식에 대해서는 다음 시간에 다룰 ‘조인’ 시간에 자세히 살펴본다.
게시판 등에 많이 사용되는 목록 쿼리에서도 ROWID를 활용할 수 있다.
SELECT 순번, 종류, 제목, 도착시간, 크기 FROM ( SELECT ROWNUM 순번, 종류, 제목, 도착시간, 크기 FROM ( SELECT /*+ INDEX(메일,메일아이디_도착시간_IDX) */ 메일.종류, 메일.제목, 메일.도착시간, 메일.크기 FROM 메일 WHERE 메일_아이디 = ‘KKK’ ORDER BY 도착시간 DESC ) ) WHERE 순번 BETWEEN 381 AND 400 AND ROWNUM < = 20
<리스트 3>의 SQL은 게시판을 구성하는 목록 쿼리의 예다. 하나의 화면에 20건의 데이터를 보여주는데, 여기에 ROWID를 적용하면 쿼리 처리 성능을 높일 수 있다.
인덱스와 테이블을 엑세스하는 부분은 랜덤 엑세스(random access)라고 한다. 이러한 랜덤 엑세스는 성능 저하의 주범이지만 이를 제거한다는 것은 결코 쉬운 일이 아니다.
SELECT /*+ INDEX(메일,메일아이디_도착시간_IDX) */ 메일.종류, 메일.제목, 메일.도착시간, 메일.크기 FROM 메일 WHERE 메일_아이디 = 'KKK' ORDER BY 도착시간 DESC
인덱스는 <리스트 4>의 SQL을 위해 메일_아이디+도착시간 인덱스를 가지고 있다. 이처럼 인덱스를 구성하면 메일_아이디+도착시간 인덱스를 엑세스한 다음 메일 테이블을 엑세스해야 하는데, 이때 랜덤 엑세스가 발생하게 된다. 해당 SQL에서 랜덤 엑세스를 제거하고 싶다면 인덱스를 다음과 같이 생성해야 한다.
메일_아이디 + 도착시간 + 종류 + 제목 + 크기
이처럼 인덱스를 생성하면 인덱스에 원하는 컬럼이 모두 존재하므로 인덱스 엑세스 후 메일 테이블을 엑세스할 필요가 없다. 즉 랜덤 엑세스가 제거된 것이다. 하지만 이처럼 컬럼의 개수를 무작정 늘리는 것에는 부담이 뒤따른다. 이런 경우에도 ROWID가 유용하게 쓰인다.
SELECT /*+ USE_NL(A B) */ A.순번, B.종류, B.제목, B.도착시간, B.크기 FROM ( SELECT 순번, RID FROM ( SELECT ROWNUM 순번, RID FROM ( SELECT /*+ INDEX(메일,메일아이디_도착시간_IDX) */ ROWID FROM 메일 WHERE 메일_아이디 = ‘KKK’ ORDER BY 도착시간 DESC ) ) WHERE 순번 BETWEEN 381 AND 400 AND ROWNUM < = 20 ) A, 메일 B WHERE A.RID = B.ROWID;
<리스트 5> SQL을 수행하는 경우를 따져보자. 인라인 뷰 A는 메일_아이디_도착시간 인덱스만 이용한다면 원하는 데이터가 모두 인덱스에 있으므로 테이블을 엑세스할 때 랜덤 엑세스가 발생하지 않는다.
- 강좌 URL : http://www.gurubee.net/lecture/2934
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.