OR-expansion 이란?
OR-expansion은 조건절에 OR 조건이나 INLISTS 조건이 있을 때 내부적으로 여러 개의 쿼리로 나누어 처리하는 기능이다.
OR-expansion 예시
예를들어 아래와 같은 쿼리가 있다.
deptno, salary 에 대한 인덱스가 있다고 가정한다.
select * from emp
where
deptno = 20
or salary > 5000;
- OR-expansinon 이 발생하지 않은 경우
OR-expansinon 이 발생하지 않은 경우, 하나의 조건절에서 여러 개의 인덱스가 사용될 수 없기 때문에 아래 실행계획과 같이 OR 조건이 full scan으로 처리된다.
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)|
|* 1 | TABLE ACCESS FULL | EMP | 14 | 448 | 3 (0)|
-------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("DEPTNO"=20 OR "SALARY">5000)
- OR-expansinon 이 발생한 경우
OR-expansion 이 발생한다면 해당 쿼리는 내부적으로 아래 쿼리와 같이 처리된다.
select * from employees
where
deptno = 20
union all
select * from employees
where
salary > 5000;
OR-expansion 으로 처리되었을 때, 아래 실행계획과 같이 각 조건에 대하여 인덱스가 적용될 수 있다.
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Pstart|
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | |
| 1 | CONCATENATION | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 5 | 2 (0)| |
|* 3 | INDEX RANGE SCAN | IDX_DEPTNO| 5 | 1 (0)| |
| 4 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 5 | 2 (0)| |
|* 5 | INDEX RANGE SCAN | IDX_SALARY| 5 | 1 (0)| |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("DEPTNO"=20)
5 - access("SALARY">5000)
OR-expansion 을 제어하는 힌트
USE_CONCAT
select /*+ USE_CONCAT */ *
from emp
where
deptno = 20
or salary > 5000;
OR-expansion 을 유도.
조건절에 OR 조건이나 INLISTS 조건이 있을 때, 쿼리가 확장된 후 CONCATENATION를 사용하여 결합되도록 유도한다.
OR로 묶인 조건들에 대하여 알맞은 인덱스가 있는 경우, USE_CONCAT 힌트를 사용하여 OR-expansion 을 유도하고 개별적으로 힌트를 탈 수 있도록 하는 것이 합리적일 수 있다.
NO_EXPAND
select /*+ NO_EXPAND */ *
from emp
where
deptno = 20
or salary > 5000;
OR-expansion 방지.
조건절에 OR 조건이나 INLISTS 조건이 있을 때, 쿼리가 확장되지 않고 그대로 실행되도록 유도한다.
OR로 묶인 조건들에 대하여 조건에 알맞은 인덱스가 없는 경우, NO_EXPAND를 사용하여 OR-expansion을 방지하고 full table scan이나 index full scan을 유도하는 것이 더 합리적일 수 있다.
'ORACLE > Admin' 카테고리의 다른 글
[Oracle] INTERSECT 명령어 (0) | 2024.04.25 |
---|---|
[ORACLE] 통계정보 수집과 백업 쿼리 (2) | 2024.01.23 |
[ORALCE] 특정 사용자만 파라미터 적용하기(LOGON TRIGGER) (0) | 2023.11.20 |
[오라클] 스키마 전체 테이블에 대한 읽기 권한 부여 (0) | 2023.10.27 |
오라클 Hash Join 원리와 use_hash 힌트 사용법 (0) | 2023.10.18 |