대메뉴 바로가기 본문 바로가기

데이터 기술 자료

데이터 기술 자료 상세보기
제목 권순용의 DB 이야기 : SQL 작성 시 ROWID 활용
등록일 조회수 4604
첨부파일  

권순용의 DB 이야기

SQL 작성 시 ROWID 활용



지난 시간에는 ROWID의 이용에 대해 살펴봤다. 이 글에서는 ROWID는 다양한 곳에 사용할 수 있는 분량 관계상 소개하지 못한 ROWID의 또 다른 활용 방안을 소개한다.



ROWID를 이용한 조인 방식은 사용자가 직접 변경할 수도 있다. <리스트 1>을 살펴보자.



<리스트 1> ROWID 조인 방식 확인 SQL> 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을 변경해야 한다.



<리스트 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를 활용하면 해시 조인을 적용 가능한 것이다.



조인 방식

조인 방식으로는 다음과 같이 세 가지 방식이 있다.

● 중첩 루프 조인(NESTED LOOPS JOIN)
● 해쉬 조인(HASH JOIN)
● 소트 머지 조인(SORT MERGE JOIN)

각각의 조인 방식에 대해서는 다음 시간에 다룰 ‘조인’ 시간에 자세히 살펴본다.



게시판 등에 많이 사용되는 목록 쿼리에서도 ROWID를 활용할 수 있다.



<리스트 3> 목록 쿼리 SQL 예 SQL> 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)라고 한다. 이러한 랜덤 엑세스는 성능 저하의 주범이지만 이를 제거한다는 것은 결코 쉬운 일이 아니다.



<리스트 4> 목록 쿼리 가장 안쪽의 SQL SQL> SELECT /*+ INDEX(메일,메일아이디_도착시간_IDX) */ 메일.종류, 메일.제목, 메일.도착시간, 메일.크기 FROM 메일 WHERE 메일_아이디 = ‘KKK’ ORDER BY 도착시간 DESC



인덱스는 <리스트 4>의 SQL을 위해 메일_아이디+도착시간 인덱스를 가지고 있다. 이처럼 인덱스를 구성하면 메일_아이디+도착시간 인덱스를 엑세스한 다음 메일 테이블을 엑세스해야 하는데, 이때 랜덤 엑세스가 발생하게 된다. 해당 SQL에서 랜덤 엑세스를 제거하고 싶다면 인덱스를 다음과 같이 생성해야 한다.

메일_아이디 + 도착시간 + 종류 + 제목 + 크기

이처럼 인덱스를 생성하면 인덱스에 원하는 컬럼이 모두 존재하므로 인덱스 엑세스 후 메일 테이블을 엑세스할 필요가 없다. 즉 랜덤 엑세스가 제거된 것이다. 하지만 이처럼 컬럼의 개수를 무작정 늘리는 것에는 부담이 뒤따른다. 이런 경우에도 ROWID가 유용하게 쓰인다.



<리스트 5> 목록 쿼리에 ROWID 적용 SQL> 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는 메일_아이디_도착시간 인덱스만 이용한다면 원하는 데이터가 모두 인덱스에 있으므로 테이블을 엑세스할 때 랜덤 엑세스가 발생하지 않는다.



출처 : 마이크로소프트웨어 5월호

제공 : 데이터전문가 지식포털 DBguide.net