반응형
Oracle DB ROWNUM과 ROWID의 완벽한 이해: 차이점, 사용법, 성능 최적화 전략
개요
Oracle 데이터베이스에서 자주 사용되지만 종종 혼동되는 두 개념인 ROWNUM과 ROWID에 대해 상세히 알아보겠습니다. 이 두 기능은 비슷해 보이지만 완전히 다른 목적을 가지고 있으며, 각각의 특성을 이해하면 쿼리 성능을 크게 개선할 수 있습니다.
ROWNUM은 쿼리 결과 집합의 각 행에 할당되는 가상 일련번호로, 페이징 처리나 상위 N개 레코드 추출에 유용합니다. 반면 ROWID는 행의 물리적 주소를 나타내는 고유 식별자로, Oracle에서 가장 빠른 데이터 접근 방법을 제공합니다.
이 글에서는 ROWNUM과 ROWID의 정의부터 구조, 사용법, 성능 차이, 실무 활용 사례까지 모든 내용을 체계적으로 다루고 있습니다. 특히 ORDER BY와 ROWNUM을 함께 사용할 때의 주의사항, ROWID를 활용한 초고속 데이터 접근 방법, 그리고 Oracle 버전별 변화까지 빠짐없이 정리했습니다.
ROWNUM은 쿼리 결과 집합의 각 행에 할당되는 가상 일련번호로, 페이징 처리나 상위 N개 레코드 추출에 유용합니다. 반면 ROWID는 행의 물리적 주소를 나타내는 고유 식별자로, Oracle에서 가장 빠른 데이터 접근 방법을 제공합니다.
이 글에서는 ROWNUM과 ROWID의 정의부터 구조, 사용법, 성능 차이, 실무 활용 사례까지 모든 내용을 체계적으로 다루고 있습니다. 특히 ORDER BY와 ROWNUM을 함께 사용할 때의 주의사항, ROWID를 활용한 초고속 데이터 접근 방법, 그리고 Oracle 버전별 변화까지 빠짐없이 정리했습니다.

목차
1. ROWNUM과 ROWID 개요
2. ROWNUM 상세 분석
3. ROWID 상세 분석
4. ROWNUM과 ROWID의 핵심 차이점
5. 실무 활용 사례 및 성능 비교
#1. ROWNUM과 ROWID 개요
Oracle 데이터베이스에서 ROWNUM과 ROWID는 각각 다른 목적으로 사용되는 중요한 개념입니다. 두 기능의 기본 개념을 먼저 이해하면 이후 내용을 더 쉽게 따라갈 수 있습니다.
1) ROWNUM이란?
ROWNUM은 Oracle이 쿼리 결과 집합의 각 행에 할당하는 가상 컬럼(pseudocolumn) 일련번호입니다. 쿼리가 처리되는 과정에서 결과 행이 반환될 때마다 1부터 순차적으로 증가하는 숫자를 부여합니다.
① ROWNUM은 쿼리 실행 시점에 동적으로 할당됩니다
② 같은 테이블이라도 다른 쿼리에서는 다른 ROWNUM 값을 가질 수 있습니다
③ 주로 페이징 처리나 상위/하위 N개 레코드 추출에 활용됩니다
④ ORDER BY 절과 함께 사용할 때 주의가 필요합니다
① ROWNUM은 쿼리 실행 시점에 동적으로 할당됩니다
② 같은 테이블이라도 다른 쿼리에서는 다른 ROWNUM 값을 가질 수 있습니다
③ 주로 페이징 처리나 상위/하위 N개 레코드 추출에 활용됩니다
④ ORDER BY 절과 함께 사용할 때 주의가 필요합니다
. . . . .
2) ROWID란?
ROWID는 Oracle 데이터베이스 내의 행(row)의 물리적 주소를 가리키는 고유 식별자입니다. 테이블의 모든 행은 생성 시점에 자동으로 할당되는 ROWID를 갖게 됩니다.
① ROWID는 18자리 문자열로 표현됩니다
② 데이터베이스 전체에서 유일한 값을 가집니다
③ Oracle에서 가장 빠른 데이터 접근 방법을 제공합니다
④ 중복 행 제거, 특정 행 직접 접근 등에 활용됩니다
① ROWID는 18자리 문자열로 표현됩니다
② 데이터베이스 전체에서 유일한 값을 가집니다
③ Oracle에서 가장 빠른 데이터 접근 방법을 제공합니다
④ 중복 행 제거, 특정 행 직접 접근 등에 활용됩니다
. . . . .
3) 두 개념의 기본 차이
ROWNUM과 ROWID는 이름은 비슷하지만 완전히 다른 특성을 가지고 있습니다.
ROWNUM은 논리적 일련번호로 쿼리마다 변경되는 반면, ROWID는 물리적 주소로 행이 존재하는 동안 유지됩니다. ROWNUM은 결과 정렬이나 필터링에 유용하고, ROWID는 특정 행에 직접 접근할 때 최고의 성능을 발휘합니다.
ROWNUM은 논리적 일련번호로 쿼리마다 변경되는 반면, ROWID는 물리적 주소로 행이 존재하는 동안 유지됩니다. ROWNUM은 결과 정렬이나 필터링에 유용하고, ROWID는 특정 행에 직접 접근할 때 최고의 성능을 발휘합니다.
#2. ROWNUM 상세 분석
ROWNUM은 Oracle 쿼리 처리 과정에서 자동으로 생성되는 가상 컬럼입니다. 이 섹션에서는 ROWNUM의 동작 원리와 올바른 사용법을 상세히 알아보겠습니다.
1) ROWNUM의 핵심 특성
ROWNUM을 제대로 활용하려면 다음 특성을 반드시 이해해야 합니다.
(1) 동적 할당 방식
ROWNUM은 쿼리 실행 시점에 동적으로 할당됩니다. 데이터베이스에 저장된 값이 아니라 쿼리 결과를 반환하는 순간 생성되는 임시 값입니다.
① 1부터 순차적으로 증가합니다
② 건너뛰는 숫자가 없습니다
③ 한 번 할당된 ROWNUM은 해당 쿼리 내에서 변경되지 않습니다
④ 쿼리가 달라지면 같은 행이라도 다른 ROWNUM을 가질 수 있습니다
① 1부터 순차적으로 증가합니다
② 건너뛰는 숫자가 없습니다
③ 한 번 할당된 ROWNUM은 해당 쿼리 내에서 변경되지 않습니다
④ 쿼리가 달라지면 같은 행이라도 다른 ROWNUM을 가질 수 있습니다
. . . . .
(2) ROWNUM 처리 순서
ROWNUM의 처리 순서는 매우 중요합니다. 이 순서를 이해하지 못하면 예상치 못한 결과가 발생할 수 있습니다.
① FROM 절 처리
② WHERE 절 처리
③ ROWNUM 할당
④ SELECT 절 처리
⑤ ORDER BY 절 처리
이 순서에서 알 수 있듯이 ORDER BY는 ROWNUM 할당 후에 처리됩니다. 이것이 ORDER BY와 ROWNUM을 함께 사용할 때 주의해야 하는 이유입니다.
① FROM 절 처리
② WHERE 절 처리
③ ROWNUM 할당
④ SELECT 절 처리
⑤ ORDER BY 절 처리
이 순서에서 알 수 있듯이 ORDER BY는 ROWNUM 할당 후에 처리됩니다. 이것이 ORDER BY와 ROWNUM을 함께 사용할 때 주의해야 하는 이유입니다.
. . . . .
2) ROWNUM 기본 사용법
ROWNUM의 기본적인 사용 예제를 살펴보겠습니다.
(1) 상위 N개 레코드 추출
-- 상위 5개 행 조회
SELECT ROWNUM, employee_id, first_name
FROM employees
WHERE ROWNUM <= 5;
-- 급여 기준 상위 5명 직원 (잘못된 방법)
SELECT ROWNUM, employee_id, first_name, salary
FROM employees
WHERE ROWNUM <= 5
ORDER BY salary DESC; -- ORDER BY는 ROWNUM 할당 후 적용됨
-- 급여 기준 상위 5명 직원 (올바른 방법)
SELECT ROWNUM, employee_id, first_name, salary
FROM (
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
)
WHERE ROWNUM <= 5;
SELECT ROWNUM, employee_id, first_name
FROM employees
WHERE ROWNUM <= 5;
-- 급여 기준 상위 5명 직원 (잘못된 방법)
SELECT ROWNUM, employee_id, first_name, salary
FROM employees
WHERE ROWNUM <= 5
ORDER BY salary DESC; -- ORDER BY는 ROWNUM 할당 후 적용됨
-- 급여 기준 상위 5명 직원 (올바른 방법)
SELECT ROWNUM, employee_id, first_name, salary
FROM (
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
)
WHERE ROWNUM <= 5;
. . . . .
(2) 페이징 처리 구현
ROWNUM을 활용한 페이징 처리는 Oracle 12c 이전 버전에서 널리 사용되는 방법입니다.
-- 11-20번째 행 가져오기 (Oracle 12c 이전)
SELECT *
FROM (
SELECT a.*, ROWNUM AS rnum
FROM (
SELECT employee_id, first_name, last_name
FROM employees
ORDER BY employee_id
) a
WHERE ROWNUM <= 20
)
WHERE rnum >= 11;
-- Oracle 12c 이상에서는 OFFSET-FETCH 사용 권장
SELECT employee_id, first_name, last_name
FROM employees
ORDER BY employee_id
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
SELECT *
FROM (
SELECT a.*, ROWNUM AS rnum
FROM (
SELECT employee_id, first_name, last_name
FROM employees
ORDER BY employee_id
) a
WHERE ROWNUM <= 20
)
WHERE rnum >= 11;
-- Oracle 12c 이상에서는 OFFSET-FETCH 사용 권장
SELECT employee_id, first_name, last_name
FROM employees
ORDER BY employee_id
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
. . . . .
3) ROWNUM 사용 시 주의사항
ROWNUM을 사용할 때 가장 흔히 발생하는 실수를 알아보겠습니다.
(1) ROWNUM > n 조건의 오류
-- 잘못된 사용: 결과가 없음
SELECT employee_id, first_name
FROM employees
WHERE ROWNUM > 1 AND ROWNUM <= 5; -- 0 rows
-- 올바른 사용: 서브쿼리 활용
SELECT *
FROM (
SELECT ROWNUM AS rnum, employee_id, first_name
FROM employees
)
WHERE rnum > 1 AND rnum <= 5;
SELECT employee_id, first_name
FROM employees
WHERE ROWNUM > 1 AND ROWNUM <= 5; -- 0 rows
-- 올바른 사용: 서브쿼리 활용
SELECT *
FROM (
SELECT ROWNUM AS rnum, employee_id, first_name
FROM employees
)
WHERE rnum > 1 AND rnum <= 5;
ROWNUM > n 조건은 직접 사용할 수 없습니다. ROWNUM은 1부터 순차적으로 할당되기 때문에 첫 번째 행이 ROWNUM > 1 조건을 만족하지 못하면 어떤 행도 반환되지 않습니다.
#3. ROWID 상세 분석
ROWID는 Oracle 데이터베이스에서 행의 물리적 위치를 나타내는 가장 중요한 식별자입니다. 이 섹션에서는 ROWID의 구조와 활용 방법을 깊이 있게 살펴보겠습니다.
1) ROWID의 구조
Oracle ROWID는 18자리 문자열로 표현되며, 다음 정보를 인코딩합니다.
(1) ROWID 구성 요소
① 데이터 객체 번호(Data Object Number): 객체가 속한 테이블스페이스 내의 고유 번호
② 데이터 파일 번호(Data File Number): 데이터 파일의 번호
③ 데이터 블록 번호(Data Block Number): 데이터 파일 내 블록 번호
④ 데이터 행 번호(Data Row Number): 블록 내 행 번호
예시: AAAE5zAAEAAAADLAAA
- AAAE5z: 데이터 객체 번호
- AAE: 데이터 파일 번호
- AAAADL: 데이터 블록 번호
- AAA: 데이터 행 번호
② 데이터 파일 번호(Data File Number): 데이터 파일의 번호
③ 데이터 블록 번호(Data Block Number): 데이터 파일 내 블록 번호
④ 데이터 행 번호(Data Row Number): 블록 내 행 번호
예시: AAAE5zAAEAAAADLAAA
- AAAE5z: 데이터 객체 번호
- AAE: 데이터 파일 번호
- AAAADL: 데이터 블록 번호
- AAA: 데이터 행 번호
. . . . .
(2) ROWID의 핵심 특성
① 고유성: 모든 행은 데이터베이스 내에서 고유한 ROWID를 갖습니다
② 불변성: 행이 존재하는 한 ROWID는 변경되지 않습니다 (특수한 경우 제외)
③ 물리적 위치: 데이터베이스 내 행의 실제 물리적 위치를 나타냅니다
④ 자동 생성: 행 삽입 시 Oracle이 자동으로 할당합니다
② 불변성: 행이 존재하는 한 ROWID는 변경되지 않습니다 (특수한 경우 제외)
③ 물리적 위치: 데이터베이스 내 행의 실제 물리적 위치를 나타냅니다
④ 자동 생성: 행 삽입 시 Oracle이 자동으로 할당합니다
. . . . .
2) ROWID 사용 방법
(1) 기본 조회
-- 테이블에서 ROWID 조회
SELECT ROWID, employee_id, first_name
FROM employees
WHERE department_id = 10;
-- ROWID를 사용한 직접 행 조회 (가장 빠른 방법)
SELECT employee_id, first_name, last_name
FROM employees
WHERE ROWID = 'AAAE5zAAEAAAADLAAA';
SELECT ROWID, employee_id, first_name
FROM employees
WHERE department_id = 10;
-- ROWID를 사용한 직접 행 조회 (가장 빠른 방법)
SELECT employee_id, first_name, last_name
FROM employees
WHERE ROWID = 'AAAE5zAAEAAAADLAAA';
. . . . .
(2) ROWID 분석 함수
Oracle은 ROWID를 분석할 수 있는 내장 함수를 제공합니다.
-- ROWID 구성 요소 추출
SELECT
DBMS_ROWID.ROWID_OBJECT(ROWID) AS object_number,
DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO(ROWID) AS file_number,
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) AS block_number,
DBMS_ROWID.ROWID_ROW_NUMBER(ROWID) AS row_number
FROM employees
WHERE employee_id = 100;
SELECT
DBMS_ROWID.ROWID_OBJECT(ROWID) AS object_number,
DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO(ROWID) AS file_number,
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) AS block_number,
DBMS_ROWID.ROWID_ROW_NUMBER(ROWID) AS row_number
FROM employees
WHERE employee_id = 100;
. . . . .
3) ROWID 변경 가능성
ROWID는 대부분의 경우 불변이지만, 다음과 같은 상황에서는 변경될 수 있습니다.
① 테이블 재구성(REORGANIZE)
② 테이블 이동(ALTER TABLE MOVE)
③ 일부 파티션 작업
④ 특정 유형의 UPDATE 작업 (행 이동이 발생하는 경우)
⑤ Export/Import 작업
따라서 ROWID를 영구적으로 저장하는 것은 권장되지 않습니다. 대신 비즈니스 키나 기본 키를 사용해야 합니다.
① 테이블 재구성(REORGANIZE)
② 테이블 이동(ALTER TABLE MOVE)
③ 일부 파티션 작업
④ 특정 유형의 UPDATE 작업 (행 이동이 발생하는 경우)
⑤ Export/Import 작업
따라서 ROWID를 영구적으로 저장하는 것은 권장되지 않습니다. 대신 비즈니스 키나 기본 키를 사용해야 합니다.
#4. ROWNUM과 ROWID의 핵심 차이점
ROWNUM과 ROWID는 근본적으로 다른 개념입니다. 두 기능의 차이점을 명확히 이해하면 적절한 상황에서 올바른 선택을 할 수 있습니다.
1) 비교표
| 항목 | ROWNUM | ROWID |
|---|---|---|
| 정의 | 쿼리 결과 집합의 가상 일련번호 | 행의 물리적 주소를 나타내는 고유 식별자 |
| 할당 시점 | 쿼리 실행 시 동적 할당 | 행 생성 시 자동 할당 |
| 유지 기간 | 쿼리 결과 내에서만 유효 | 행이 존재하는 동안 유지 |
| 변경 가능성 | 쿼리에 따라 변경됨 | 행이 이동하지 않는 한 변경되지 않음 |
| 주요 용도 | 페이징, 상위/하위 N개 행 추출 | 특정 행의 직접 접근, 중복 제거 |
| 유일성 | 쿼리 내에서 유일 (1부터 순차적) | 데이터베이스 전체에서 유일 |
| 접근 방식 | 논리적 접근 | 물리적 접근 |
| 성능 | 쿼리마다 재계산 필요 | 가장 빠른 단일 행 접근 |
. . . . .
2) 사용 시나리오별 선택 가이드
(1) ROWNUM을 사용해야 하는 경우
① 페이징 처리가 필요한 경우
② 상위/하위 N개 레코드를 추출해야 하는 경우
③ 쿼리 결과에 순번을 매겨야 하는 경우
④ 샘플 데이터를 추출해야 하는 경우
⑤ 배치 처리에서 일정 개수씩 데이터를 처리해야 하는 경우
② 상위/하위 N개 레코드를 추출해야 하는 경우
③ 쿼리 결과에 순번을 매겨야 하는 경우
④ 샘플 데이터를 추출해야 하는 경우
⑤ 배치 처리에서 일정 개수씩 데이터를 처리해야 하는 경우
. . . . .
(2) ROWID를 사용해야 하는 경우
① 특정 행에 가장 빠르게 접근해야 하는 경우
② 중복 행을 식별하고 제거해야 하는 경우
③ 테이블 간 조인 성능을 최적화해야 하는 경우
④ 행의 물리적 위치 정보가 필요한 경우
⑤ 배치 작업에서 처리한 행을 추적해야 하는 경우 (단기적으로)
② 중복 행을 식별하고 제거해야 하는 경우
③ 테이블 간 조인 성능을 최적화해야 하는 경우
④ 행의 물리적 위치 정보가 필요한 경우
⑤ 배치 작업에서 처리한 행을 추적해야 하는 경우 (단기적으로)
#5. 실무 활용 사례 및 성능 비교
이 섹션에서는 ROWNUM과 ROWID의 실무 활용 사례와 성능 비교를 통해 실전에서 어떻게 활용할 수 있는지 알아보겠습니다.
1) ROWNUM 실무 활용
(1) 페이징 처리 최적화
-- Oracle 12c 이전: 3단계 서브쿼리 방식
SELECT *
FROM (
SELECT a.*, ROWNUM AS rnum
FROM (
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
) a
WHERE ROWNUM <= 20
)
WHERE rnum >= 11;
-- Oracle 12c 이상: OFFSET-FETCH 방식 (권장)
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
SELECT *
FROM (
SELECT a.*, ROWNUM AS rnum
FROM (
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
) a
WHERE ROWNUM <= 20
)
WHERE rnum >= 11;
-- Oracle 12c 이상: OFFSET-FETCH 방식 (권장)
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
. . . . .
(2) 랜덤 샘플링
-- 랜덤 샘플 100개 추출
SELECT employee_id, first_name, department_id
FROM (
SELECT employee_id, first_name, department_id
FROM employees
ORDER BY DBMS_RANDOM.VALUE
)
WHERE ROWNUM <= 100;
SELECT employee_id, first_name, department_id
FROM (
SELECT employee_id, first_name, department_id
FROM employees
ORDER BY DBMS_RANDOM.VALUE
)
WHERE ROWNUM <= 100;
. . . . .
2) ROWID 실무 활용
(1) 중복 데이터 제거
-- 중복 행 중 하나만 남기고 삭제
DELETE FROM employees
WHERE ROWID NOT IN (
SELECT MIN(ROWID)
FROM employees
GROUP BY employee_id, email
);
-- 또는 EXISTS 사용 (더 효율적)
DELETE FROM employees e1
WHERE ROWID > (
SELECT MIN(ROWID)
FROM employees e2
WHERE e1.employee_id = e2.employee_id
AND e1.email = e2.email
);
DELETE FROM employees
WHERE ROWID NOT IN (
SELECT MIN(ROWID)
FROM employees
GROUP BY employee_id, email
);
-- 또는 EXISTS 사용 (더 효율적)
DELETE FROM employees e1
WHERE ROWID > (
SELECT MIN(ROWID)
FROM employees e2
WHERE e1.employee_id = e2.employee_id
AND e1.email = e2.email
);
. . . . .
(2) 초고속 단일 행 업데이트
-- ROWID를 사용한 가장 빠른 업데이트
UPDATE employees
SET salary = salary * 1.1
WHERE ROWID = 'AAAE5zAAEAAAADLAAA';
-- 인덱스 스캔보다 빠른 ROWID 활용
UPDATE employees
SET last_update = SYSDATE
WHERE ROWID IN (
SELECT ROWID
FROM employees
WHERE department_id = 10
AND hire_date < SYSDATE - 365
);
UPDATE employees
SET salary = salary * 1.1
WHERE ROWID = 'AAAE5zAAEAAAADLAAA';
-- 인덱스 스캔보다 빠른 ROWID 활용
UPDATE employees
SET last_update = SYSDATE
WHERE ROWID IN (
SELECT ROWID
FROM employees
WHERE department_id = 10
AND hire_date < SYSDATE - 365
);
. . . . .
3) 성능 비교
일반적인 시나리오에서 ROWID, 인덱스, ROWNUM의 성능을 비교해보겠습니다.
| 접근 방식 | 100만 행 테이블 (ms) | 상대적 성능 | 적합한 사용 사례 |
|---|---|---|---|
| ROWID 직접 접근 | 1 | 가장 빠름 (1x) | 특정 행 직접 접근 |
| 기본 키 인덱스 | 2-3 | 2-3배 느림 | 일반적인 단일 행 조회 |
| 일반 인덱스 | 3-5 | 3-5배 느림 | 조건에 맞는 행 검색 |
| ROWNUM ≤ 1 | 2-10 | 쿼리 복잡도에 따라 변동 | 첫 번째 행 조회 |
| 전체 테이블 스캔 | 100-500 | 100-500배 느림 | 대량 데이터 처리 |
. . . . .
4) Oracle 버전별 변화
(1) Oracle 12c의 혁신
Oracle 12c에서는 ROW_LIMITING 절이 도입되어 ROWNUM을 사용한 복잡한 서브쿼리를 대체할 수 있게 되었습니다.
① OFFSET-FETCH 구문 지원
② Top-N 쿼리 최적화 기능 강화
③ 페이징 처리 성능 개선
④ 코드 가독성 향상
① OFFSET-FETCH 구문 지원
② Top-N 쿼리 최적화 기능 강화
③ 페이징 처리 성능 개선
④ 코드 가독성 향상
-- Oracle 12c 이상의 간결한 페이징
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
-- 퍼센트 기반 조회도 가능
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 10 PERCENT ROWS ONLY;
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
-- 퍼센트 기반 조회도 가능
SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 10 PERCENT ROWS ONLY;
. . . . .
(2) Oracle 19c/21c의 개선
① 분석 함수와 ROWNUM의 병렬 처리 기능 향상
② 메모리 최적화를 통한 ROWID 접근 성능 개선
③ 자동 메모리 관리 기능 강화
④ 인덱스 스캔 알고리즘 최적화
② 메모리 최적화를 통한 ROWID 접근 성능 개선
③ 자동 메모리 관리 기능 강화
④ 인덱스 스캔 알고리즘 최적화
. . . . .
5) 자주 묻는 질문 (FAQ)
(1) ROWNUM과 ROW_NUMBER()의 차이는?
ROWNUM은 pseudocolumn으로 ORDER BY 전에 할당되는 반면, ROW_NUMBER()는 분석 함수로 정렬된 결과에 번호를 매깁니다. ROW_NUMBER()는 PARTITION BY를 통해 그룹별 번호 부여가 가능합니다.
-- ROW_NUMBER() 예제
SELECT
employee_id,
department_id,
salary,
ROW_NUMBER() OVER(
PARTITION BY department_id
ORDER BY salary DESC
) AS dept_rank
FROM employees;
SELECT
employee_id,
department_id,
salary,
ROW_NUMBER() OVER(
PARTITION BY department_id
ORDER BY salary DESC
) AS dept_rank
FROM employees;
. . . . .
(2) ROWID는 항상 불변인가요?
아니요, 다음 상황에서 변경될 수 있습니다.
① 테이블 재구성(REORGANIZE)
② 행 이동(특정 UPDATE 작업)
③ 테이블 이동(ALTER TABLE MOVE)
④ 파티션 작업
⑤ Export/Import
따라서 ROWID를 영구 저장하는 것은 권장되지 않습니다.
① 테이블 재구성(REORGANIZE)
② 행 이동(특정 UPDATE 작업)
③ 테이블 이동(ALTER TABLE MOVE)
④ 파티션 작업
⑤ Export/Import
따라서 ROWID를 영구 저장하는 것은 권장되지 않습니다.
. . . . .
(3) 대용량 페이징에는 무엇이 효율적인가요?
① Oracle 12c 이상: OFFSET-FETCH 구문 사용 (가장 권장)
② 이전 버전: 인덱스를 활용한 범위 스캔 + ROWNUM
③ 매우 큰 OFFSET: Seek Method(마지막 값 기준 조회) 활용
ROWID는 페이징보다는 특정 행 직접 접근에 적합합니다.
② 이전 버전: 인덱스를 활용한 범위 스캔 + ROWNUM
③ 매우 큰 OFFSET: Seek Method(마지막 값 기준 조회) 활용
ROWID는 페이징보다는 특정 행 직접 접근에 적합합니다.
마무리
ROWNUM과 ROWID는 Oracle 데이터베이스에서 서로 다른 목적으로 사용되는 핵심 기능입니다.
ROWNUM은 쿼리 결과에 동적으로 할당되는 가상 일련번호로, 페이징 처리와 상위/하위 N개 레코드 추출에 유용합니다. 특히 ORDER BY와 함께 사용할 때는 반드시 서브쿼리 구조를 활용해야 올바른 결과를 얻을 수 있습니다. Oracle 12c 이상에서는 OFFSET-FETCH 구문이 더 간결하고 효율적입니다.
ROWID는 행의 물리적 주소를 나타내는 고유 식별자로, Oracle에서 가장 빠른 데이터 접근 방법을 제공합니다. 특정 행에 직접 접근, 중복 행 제거, 테이블 조인 최적화 등에 탁월한 성능을 발휘합니다. 단, ROWID는 영구 저장보다는 임시 참조 용도로 사용하는 것이 안전합니다.
두 기능의 특성을 정확히 이해하고 적절한 상황에서 활용한다면, Oracle 데이터베이스의 성능을 크게 향상시킬 수 있습니다. 특히 대용량 데이터를 다루는 엔터프라이즈 환경에서는 이러한 기본 개념의 깊은 이해가 성능 최적화의 핵심 요소가 됩니다.
실무에서는 다음 원칙을 기억하세요.
① 페이징과 Top-N 쿼리에는 ROWNUM (또는 Oracle 12c 이상에서는 OFFSET-FETCH) 활용
② 특정 행 직접 접근과 중복 제거에는 ROWID 활용
③ ORDER BY와 ROWNUM을 함께 사용할 때는 서브쿼리 필수
④ ROWID를 영구 저장하지 말고 비즈니스 키 사용
⑤ 버전별 최적화 기능(12c의 OFFSET-FETCH 등) 적극 활용
ROWNUM은 쿼리 결과에 동적으로 할당되는 가상 일련번호로, 페이징 처리와 상위/하위 N개 레코드 추출에 유용합니다. 특히 ORDER BY와 함께 사용할 때는 반드시 서브쿼리 구조를 활용해야 올바른 결과를 얻을 수 있습니다. Oracle 12c 이상에서는 OFFSET-FETCH 구문이 더 간결하고 효율적입니다.
ROWID는 행의 물리적 주소를 나타내는 고유 식별자로, Oracle에서 가장 빠른 데이터 접근 방법을 제공합니다. 특정 행에 직접 접근, 중복 행 제거, 테이블 조인 최적화 등에 탁월한 성능을 발휘합니다. 단, ROWID는 영구 저장보다는 임시 참조 용도로 사용하는 것이 안전합니다.
두 기능의 특성을 정확히 이해하고 적절한 상황에서 활용한다면, Oracle 데이터베이스의 성능을 크게 향상시킬 수 있습니다. 특히 대용량 데이터를 다루는 엔터프라이즈 환경에서는 이러한 기본 개념의 깊은 이해가 성능 최적화의 핵심 요소가 됩니다.
실무에서는 다음 원칙을 기억하세요.
① 페이징과 Top-N 쿼리에는 ROWNUM (또는 Oracle 12c 이상에서는 OFFSET-FETCH) 활용
② 특정 행 직접 접근과 중복 제거에는 ROWID 활용
③ ORDER BY와 ROWNUM을 함께 사용할 때는 서브쿼리 필수
④ ROWID를 영구 저장하지 말고 비즈니스 키 사용
⑤ 버전별 최적화 기능(12c의 OFFSET-FETCH 등) 적극 활용
긴 글 읽어주셔서 감사합니다.
끝.
끝.
반응형
'Development > Database' 카테고리의 다른 글
| [DB] Oracle SQL 완벽 정리 (0) | 2022.08.31 |
|---|---|
| [DB] Oracle Listener 구성부터 관리까지 완벽 분석 (1) | 2020.04.08 |
| [DB] Oracle Sequence 생성과 활용 방법 - 기본부터 성능 최적화까지 (0) | 2020.04.08 |
| [DB] ORACLE DB 사용자 계정 패스워드 없애는 방법 (0) | 2020.04.08 |
| [DB] ORACLE DB SYSTEM, SYS 암호 변경 (0) | 2020.04.08 |