SQL) 쿼리 변환 Ⅱ

jinsung·2026년 1월 8일

SQL

목록 보기
38/46
post-thumbnail

4. 조건절 Pushing

이떤 이유에서건 뷰 Merging 을 실패했을 때, 옵티마이저는 포기하지 않고 2차적으로 조건절 Pushing을 시도한다.
조건절 Pushing은 참조하는 쿼리 블록의 조건절을 뷰 쿼리 블록 안으로 Pushing 하는 기능을 말한다.

조건절이 가능한 빨리 처리되도록 뷰 안으로 밀어 넣는다면, 뷰 안에서의 처리 일량을 최소화하게 됨은 물론 리턴되는 결과 건수를 줄임으로써 다음 단계에서 처리해야 할 일량을 줄일 수 있다.

☑️ 조건절 Pushing 종류

1. 조건절 Pushdown

쿼리 블록 밖에 있는 조건들을 쿼리 블록 안쪽으로 밀어넣는 것을 말한다.

2. 조건절 Pullup

쿼리 블록 안에 있는 조건들을 쿼리 블록 밖으로 내오는 것을 말하며, 그것을 다시 다른 쿼리 블록에 Pushdown 하는 데 사용한다.

3. 조인조건 Pushdown

NL 조인 수행 중에 Outer 테이블에서 읽은 값을 건건이 Inner 쪽 뷰 쿼리 블록 안으로 밀어 넣는 것을 말한다.

조인 조건 Pushdown은 NL 조인을 전제로 하기 때문에 성능이 더 나빠질 수 있다.
따라서 오라클은 push_pred, no_push_pred 힌트를 제공한다.

9i 에서 use_nl 힌트를 push_pred 와 함께 사용하면 조인 조건 Pushdown 기능이 작동하지 않는 현상이 나타난다.
이때는 push_pred 힌트만을 사용해야 하며, 조인 조건 Pushdown은 NL 조인을 전제로 하므로 굳이 use_nl 힌트를 쓸 필요가 없다.

✅ Outer 조인 뷰에 대한 조인 조건 Pushdown

Outer 조인에서 Inner 쪽 집합이 뷰 쿼리 블록 일 때, 뷰 안에서 참조하는 테이블 개수에 따라 옵티마이저는 두 가지 방법 중 하나를 선택한다.

  1. 뷰 안에 참조하는 테이블이 단 하나일 때, 뷰 Merging을 시도한다.

  2. 뷰 내에서 참조하는 테이블이 두 개 이상일 때, 조인 조건식을 뷰 안쪽으로 Pushing하려고 시도한다.


5. 조건절 이행

조건절 이행은 A=B 이고 B=C 이면 A=C라는 추론을 통해 새로운 조건절을 내부적으로 생성해 주는 쿼리 변환이다. (<, > 부등호도 상관없다.)

상수 및 변수에 대한 조건절은 조인문을 타고 다른 쪽 테이블로 전이된다.
하지만 조인문 자체는 전이되지 않는다.

조인조건은 상수와 변수 조건처럼 전이되지 않으므로 최적의 조인순서를 결정하고 그 순서에 따라 조인문을 기술해 주는 것이 매우 중요하다.


6. 조인 제거

1:M 관계인 두 테이블을 조인하는 쿼리문에서 조인문을 제외한 어디에서도 1쪽 테이블을 참조하지 않는다면, 쿼리 수행시 1쪽 테이블은 읽지 않아도 된다.
결과집합에 영향을 주지 않기 때문이다.

옵티마이저는 이 특성을 이용해 M쪽 테이블만 읽도록 쿼리를 변환하는데, 이를 '조인 제거' 나 ' 테이블 제거' 라고 한다.

alter session set "_optimizer_join_elimination_enabled" = true;

이 기능을 제어하는 파라미터는 위와 같고, eliminate_join, no_eliminate_join 힌트를 통해 제어한다.

조인 제거 기능이 작동하려면 PK/FK 제약이 설정돼 있어야한 한다.


7. OR-Expansion

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로 분기 해 줘야만 한다.


8. 공통 표현식 제거

같은 조건식이 여러 곳에 반복 사용될 경우, 오라클은 해당 조건식이 각 로우당 한 번씩만 평가되도록 쿼리를 변환하는데 이를 '공통 표현식 제거' 라고 한다.
_eliminate_common_subexpxr 파라미터를 통해 제어한다.

profile
Data Engineer

0개의 댓글