DBDBDEEP
OR Expansion 본문
where ( 전화번호 =:tel_no OR 고객명 = :cust_nm)
과 같이 OR 조건으로 검색하는 경우 수직적 탐색을 통해 전화번호가 '01012345678' 이거나
고객명이 '홍길동'인 어느 한 시작지점을 바로 찾을 수 없다.
위 쿼리를 아래와 같이 변경하면 고객명, 전화번호 인덱스 각각에 대해 Index Range Scan이 가능하게 된다.
| select * from 고객 where 고객명 = :cust_nm -- 고객명이 선두 컬럼인 인덱스 Range Scan union all select * from 고객 where 전화번호 = :tel_no -- 전화번호가 선두 컬럼인 인덱스 Range Scan and (고객명 <> :cust_nm or 고객명 is null) |

/*+ USE_CONCAT */ 은 OR Expansion 을 할 수 있게 해주는 힌트이다.
반대로 /*+ NO_EXPAND */ 는 OR Expansion을 할 수 없게 해주는 힌트이다.
where 전화번호 in ( :tel_no1, :tel_no2 ) 이러한 조건절은 어떻게 될까?
IN 조건은 OR조건을 표현하는 다른 방식이기 때문에, UNION ALL 방식으로
| select * from 고객 where 전화번호 = :tel_no1 union all select * from 고객 where 전화번호 = : tel _no2 |
그래서 IN 조건절에 대해서는 SQL 옵티마이저가 IN-List Iterator 방식을 사용한다.

(nvl/decode 조건식에 대한 OR-Expansion도 가능하다.
사용자가 선택적으로 입력하는 조건절에 대해 nvl 또는 decode 함수를 이용할 수 있다
select * from emp
where deptno = nvl(:deptno, deptno)
and ename like :ename || '%'
;
오라클 9i부터 쿼리를 위와 같이 작성하면, 아래와 같은 형태로OR-Expansion 쿼리 변환이 일어난다.
select * from emp
where :deptno is null
and deptno is not null
and ename like :ename || '%'
union all
select * from emp
where :deptno is not null
and deptno = :deptno
and ename like :ename || '%' ;
'친절한 SQL 튜닝' 카테고리의 다른 글
| 2.2.7 자동 형변환 (0) | 2026.05.16 |
|---|---|
| 2.2.3 인덱스 사용 조건 (0) | 2026.05.16 |
| 2.1.5 결합 인덱스 구조와 탐색 (0) | 2026.05.16 |
| 2.1.3 인덱스 수직/수평적 탐색 (0) | 2026.05.16 |
| 1.3.6 Single Block,Multi Block I/O (0) | 2026.05.16 |