ROWID를 이용한 조인으로 SQL 튜닝
- large_table과 small_table이라는 두 테이블을 조인하는 상황
- large_table에서 small_table의 특정 조건을 만족하는 데이터를 찾을 때, ROWID를 사용하면 물리적인 위치를 직접 참조하여 논리적인 인덱스 스캔보다 효율적일 수 있습니다.
SELECT
t1.column1,
t1.column2,
t2.column_a
FROM
large_table t1
WHERE
t1.rowid IN (
SELECT /*+ cardinality(t2, 100) */
t1_alias.rowid
FROM
large_table t1_alias,
small_table t2
WHERE
t1_alias.join_column = t2.join_column
AND t2.some_condition = 'value'
);
성능 개선 원리
- ROWID를 이용한 조인이 항상 성능을 개선하는 것은 아님
- 대규모 테이블과 소규모 테이블 조인시 효과적
- - 소규모 테이블에서 먼저 조건을 만족하는 데이터를 찾고, 그에 해당하는 대규모 테이블의 ROWID를 얻어 대규모 테이블에 직접 접근하는 방식
- - 이렇게 하면 불필요한 대규모 테이블 전체 스캔을 방지할 수 있음
- 서브쿼리 최적화: 서브쿼리에서 ROWID를 사용하여 메인 쿼리로 전달하면, 옵티마이저는 이를 'by rowid' 방식으로 처리하여 물리적인 블록 주소를 이용한 빠른 접근이 가능해집니다.
- 특정 인덱스 스캔 대체: 인덱스 스캔은 B-트리 구조를 탐색하는 논리적인 과정이 필요하지만, ROWID를 직접 사용하면 해당 데이터 블록으로 바로 이동하므로, 인덱스 리프 노드에서 ROWID를 얻어 테이블에 접근하는 일반적인 방식보다 더 효율적인 경우가 있습니다.
주의사항
- ROWID는 물리적인 주소를 나타내므로, 테이블에 데이터가 추가되거나 삭제, 또는 ALTER TABLE ... MOVE와 같은 DDL 작업이 발생하면 ROWID 값이 변경될 수 있습니다.
- 따라서 ROWID는 동일 세션 내에서 일시적으로 사용하는 것이 좋으며, 영구적인 식별자로 사용해서는 안 됩니다.
- 파티션 테이블의 경우 ROWID가 파티션 정보를 포함하므로 이 점을 고려해야 합니다.