[DB] 쿼리 변환 - 조건절 Pushing

최민석·2021년 7월 28일
1

포기하지 않는 옵티마이저

옵티마이저는 뷰 머징을 여러 이유에서건 실패하였을떄, 바로 2차적으로 조건절 Pushing을 시도한다.
단순 뷰에서, 조건절을 인라인뷰 안에넣어서, 조건을 먼저 필터링하고 조인한다면 좋은 성능을 기대 할것이다.

조건절 Pushing의 종류

  • 조건절 Pushdown : 쿼리 블록 밖에 있는 조건들을 쿼리 블록 안쪽으로 밀어 넣는 것을 말함.
  • 조건절 Pullup : 쿼리블록 안에있는 조건들을 쿼리 블록 밖으로 꺼내오는 것을 말하며, 그것을 다시 다른 쿼리 블록에 Pushdown 하는데 사용함.
  • 조인 조건 Pushdown : NL조인 수행중에 드라이빙 테이블에서 읽은 값을 건건이 Inner 쪽 뷰 쿼리블록 안으로 밀어 넣는 것을 말함.

여기서 조건절 Pushdown, Pullup은 항상 더 나은 성능을 보장하므로 별도의 힌트가 없다. 하지만 조인 조건 Pushdown은 NL조인을 전제로 하기때문에 성능이 더 나빠질 수 있다. 따라서 이를 제어하는 push_pred, no_push_pred를 제공한다.

참고로 rownum 조건과 분석함수를 사용할땐 non-mergeable 이 되었고 동시에 non-pushable 도 같이 적용된다.
그어떤 경우도 결과 집합에 변화가 있으면 안된다는 법칙떄문이다.

조건절 Pushing

먼저 쿼리를 보자.

자동으로 뷰 merge를 막기위해 no_merge 힌트를 사용하였고, 인라인뷰의 그룹작업이 끝나면 deptno = 30 으로 필터링 되게 했다.

하지만 실행계획은 조건절(deptno=30)이 인라인뷰로 푸쉬되어
먼저 deptno를 검사(id 4)하고 필터된 레코드만 그룹화 하는것을 볼수 있다.

조건절 Pullup

예제 쿼리르 보자.
똑같이 emp를 인라인뷰에 사용하고 있지만, e1만 조건절에 deptno=10이라는 조건을 추가했다.

실행계획이다.
e1과 e2 모두 필터 조건으로 deptno=10으로 걸러지고 있다.
이는 e1의 조건절이 Pullup되어 메인쿼리 조건절로 나왔고, 다시 조건절 Pushdown으로 e2 인라인뷰 속으로 들어간 것이다.


힌트 조건으로 opt_param('_pred_move_around', 'false') 를 줌으로 인해 조건절 Pullup은 일어났지만, Pushdown은 일어나지 않은 결과이다.


조건절 Pushdown이 일어나지 않아 id7번의 계획이 풀스캔으로 14rows를 반환하고 있다.

조건 조인 Pushdown

조건 조인 Pushdown은 조건절 pushdown의 한 종류이지만, 좀더 세분화 하기로 한다. 바로 상수를 필터링 하는 것과 다른 조인 조건절을 뷰에 Push한다.

예제 쿼리이다. push_pred(e) 힌트로 조인 조건 pushdown을 유도한다.
d테이블과 e테이블을 조인 하지만, emp 테이블의 풀스캔이 불가피 해보인다.


실행 계획이다. 아우터 조인에 의해 드라이빙 테이블이 dept로 정해졌고, emp 테이블은 풀스캔이 불가피 해보였지만, 조인 조건 pushdown에 의해 id5번 인덱스 레인지 스캔이 가능했다. 액세스 경로를 보면 deptno = d.deptno 로 상수형 조건이 아닌 조인 조건이 push된것을 볼 수 있다

그리고 조인 조건 pushdown은 NL조인을 전제로 진행하므로 use_nl 힌트를 굳이 사용할 필요는 없다.

조건절 이행

a=b, b=c 일때 a=c

간단하다. 위와 같은 논리로, 조건절이 이동하며 최적의 결과를 고려한다.
바로 예제를 보자.

예제

select * from dept d, emp e
where e.job = 'manager'
and e.deptno = 10
and d.deptno = e.deptno

일떄 실행 계획을 보면 dept 테이블에도 deptno = 10이라는 필터 조건이 추가된다.

select * from dept d, emp e
where e.job = 'manager'
and e.deptno = 10
and d.deptno = 10

바로 이런 형태로 조건절이 이행된다.
e.deptno=10 이고, d.deptno = e.deptno 일떄 d.deptno=10이다.

위와 같이 변환될때 해시 조인 또는 소트 머지을 수행하기전에 emp와 dept테이블에 각각 필터링을 적용하므로써 조인되는 데이터량을 줄일 수 있다.

profile
🔥🔥🔥🔥 G U N F E 🔥🔥🔥🔥

0개의 댓글