이떤 이유에서건 뷰 Merging 을 실패했을 때, 옵티마이저는 포기하지 않고 2차적으로 조건절 Pushing을 시도한다.
조건절 Pushing은 참조하는 쿼리 블록의 조건절을 뷰 쿼리 블록 안으로 Pushing 하는 기능을 말한다.
조건절이 가능한 빨리 처리되도록 뷰 안으로 밀어 넣는다면, 뷰 안에서의 처리 일량을 최소화하게 됨은 물론 리턴되는 결과 건수를 줄임으로써 다음 단계에서 처리해야 할 일량을 줄일 수 있다.
쿼리 블록 밖에 있는 조건들을 쿼리 블록 안쪽으로 밀어넣는 것을 말한다.
쿼리 블록 안에 있는 조건들을 쿼리 블록 밖으로 내오는 것을 말하며, 그것을 다시 다른 쿼리 블록에 Pushdown 하는 데 사용한다.
NL 조인 수행 중에 Outer 테이블에서 읽은 값을 건건이 Inner 쪽 뷰 쿼리 블록 안으로 밀어 넣는 것을 말한다.
조인 조건 Pushdown은 NL 조인을 전제로 하기 때문에 성능이 더 나빠질 수 있다.
따라서 오라클은 push_pred, no_push_pred 힌트를 제공한다.
9i 에서 use_nl 힌트를 push_pred 와 함께 사용하면 조인 조건 Pushdown 기능이 작동하지 않는 현상이 나타난다.
이때는 push_pred 힌트만을 사용해야 하며, 조인 조건 Pushdown은 NL 조인을 전제로 하므로 굳이 use_nl 힌트를 쓸 필요가 없다.
Outer 조인에서 Inner 쪽 집합이 뷰 쿼리 블록 일 때, 뷰 안에서 참조하는 테이블 개수에 따라 옵티마이저는 두 가지 방법 중 하나를 선택한다.
뷰 안에 참조하는 테이블이 단 하나일 때, 뷰 Merging을 시도한다.
뷰 내에서 참조하는 테이블이 두 개 이상일 때, 조인 조건식을 뷰 안쪽으로 Pushing하려고 시도한다.
조건절 이행은 A=B 이고 B=C 이면 A=C라는 추론을 통해 새로운 조건절을 내부적으로 생성해 주는 쿼리 변환이다. (<, > 부등호도 상관없다.)
상수 및 변수에 대한 조건절은 조인문을 타고 다른 쪽 테이블로 전이된다.
하지만 조인문 자체는 전이되지 않는다.
조인조건은 상수와 변수 조건처럼 전이되지 않으므로 최적의 조인순서를 결정하고 그 순서에 따라 조인문을 기술해 주는 것이 매우 중요하다.
1:M 관계인 두 테이블을 조인하는 쿼리문에서 조인문을 제외한 어디에서도 1쪽 테이블을 참조하지 않는다면, 쿼리 수행시 1쪽 테이블은 읽지 않아도 된다.
결과집합에 영향을 주지 않기 때문이다.
옵티마이저는 이 특성을 이용해 M쪽 테이블만 읽도록 쿼리를 변환하는데, 이를 '조인 제거' 나 ' 테이블 제거' 라고 한다.
alter session set "_optimizer_join_elimination_enabled" = true;
이 기능을 제어하는 파라미터는 위와 같고, eliminate_join, no_eliminate_join 힌트를 통해 제어한다.
조인 제거 기능이 작동하려면 PK/FK 제약이 설정돼 있어야한 한다.
select *
from emp
where job = 'CLERK' or deptno = 20;
위 쿼리가 그대로 수행된다면 or 조건이므로 Full Table Scan 으로 처리되거나 Index Combine이 작동할 수 있다.
만약 job과 deptno에 각각 생성된 인덱스를 사용하고 싶다면 union all 형태로 바꿔주면 된다.
사용자가 쿼리를 직접 바꿔주지 않아도 옵티마이저가 그런 작업을 대신해 주는 경우가 있는데 이를 'OR-Expansion' 이라고 한다.
OR-Expansion을 제어하기 위해 사용하는 힌트는 use_concat, no_expand 두가지가 있다.
use_concat은 OR-Expansion을 유도할 때 사용하고, no_expand는 방지할 때 사용한다.
9i까지는 같은 컬럼에 대한 or 조건이나 in-list도 or-expansion으로 작동할 수 있었다.
10g 부터는 기본적으로 in-list iterator 방식으로 작동한다. (비교연산자가 '=' 일 시)
nvl 또는 decode를 여러 컬럼에 대해 사용했을 때는 그 중 변별력이 가장 좋은 컬럼으로 한 번만 분기가 일어난다.
옵션 조건이 복잡할 때는 이 방식에만 의존하기 어려운 이유가 여기에 있고, 그럴 때는 수동으로 union all로 분기 해 줘야만 한다.
같은 조건식이 여러 곳에 반복 사용될 경우, 오라클은 해당 조건식이 각 로우당 한 번씩만 평가되도록 쿼리를 변환하는데 이를 '공통 표현식 제거' 라고 한다.
_eliminate_common_subexpxr 파라미터를 통해 제어한다.