PUSH JOIN PREDICATE
EXEM Knowledge Base
목차 |
[편집] 기본 정보
[편집] Parameter 정보
| Syntax | _PUSH_JOIN_PREDICATE |
| 설정방법 |
|
| 버전 및 기본값 |
| 9iR2 | 10gR1 | 10gR2 | 11g |
|---|---|---|---|
| TRUE | TRUE | TRUE | TRUE |
[편집] 설명
_PUSH_JOIN_PREDIATE 파라미터는 Join Predicate를 View의 텍스트안으로 Push하는 기능을 결정한다. Oracle은 View를 사용하는 쿼리에 대해 우선적으로 Complex View Merging을 시도하고 이것이 불가능한 뷰에 대해서는 Join Predicate Pushing을 시도한다.
View Merging이 불가능한 뷰(Nonmergeable View)는 다음과 같은 기능을 사용하는 View를 의미한다.
- Set operators (UNION, UNION ALL, INTERSECT, MINUS)
- A CONNECT BY clause
- A ROWNUM pseudocolumn
- Aggregate functions (AVG, COUNT, MAX, MIN, SUM) in the select list
Oracle은 항상 Join Predicate Pushing을 시도하지만 View의 속성에 따라 불가능한 경우도 있음에 주의해야 한다. 가령 일반적으로 View가 UNION ALL 절이나 OUTER JOIN 절을 사용하면 Join Predicate Pushing이 이루어지지 않는다. Join Predicate Pushing이 작동하는 방식은 Oracle Version마다 다르기 때문에 반드시 Version별로 확인해 보아야 한다.
Oracle 10g에서는 Cost에 기반하여 Join Predicate Pushing기능을 제어하는 기능이 추가되었으며, _OPTIMIZER_PUSH_PRED_COST_BASED 파라미터로 사용 여부를 지정한다. 이 파라미터의 값은 기본값 True이다. 만일 9i 버전에서는 Join Predicate Pushing이 동작하여 Query의 성능이 좋았음에도 불구하고 10g로 업그레이드후 Join Predicate Pushing이 동작하지 않는다면 해당 파라미터의 값을 False로 변경함으로써 해결할 수 있다.
[편집] 참고 사항
[편집] Join Predicate Pushing의 적용 예
Join Predicate Pushing의 적용 예는 아래와 같다.
-- UNION 구문을 사용하는 View. UNION 구문에 의해 View Merging이 불가능하다.
CREATE VIEW two_emp_tables
(employee_id, last_name, job_id, manager_id, hire_date, salary,
commission_pct, department_id) AS
SELECT employee_id, last_name, job_id, manager_id, hire_date, salary,
commission_pct, department_id
FROM emp1
UNION
SELECT employee_id, last_name, job_id, manager_id, hire_date,
salary, commission_pct, department_id
FROM emp2;
-- View를 액세하는 쿼리
SELECT employee_id, last_name
FROM two_emp_tables
WHERE department_id = 50;
-- 위의 쿼리는 Join Predicate Pushing에 의해 아래와 같이 변환된다.
SELECT employee_id, last_name
FROM ( SELECT employee_id, last_name, job_id, manager_id, hire_date,
salary, commission_pct, department_id
FROM emp1
WHERE department_id = 50 -- Predicate가 Subquery안으로 Push됨
UNION
SELECT employee_id, last_name, job_id, manager_id, hire_date,
salary, commission_pct, department_id
FROM emp2
WHERE department_id = 50 ); -- Predicate가 Subquery안으로 Push됨
[편집] 잘못된 Join Predicate Pushing에 의한 성능 저하
Join Predicate Pushing은 대단히 바람직한 기능이며, 일반적으로 성능을 개선시키는 효과가 있다. 하지만 특정 쿼리에서, 특히 복잡한 쿼리에서는 오히려 잘못된 실행 계획을 만드는 역효과를 가지고 있다. 이 경우에는 Join Predicate Pushing을 비활성화함으로써 문제를 해결할 수 있다. 다음과 같은 방법으로 비활성화할 수 있다.
-- _PUSH_JOIN_PREDICATE 파라미터를 False로 변경한다.
ALTER SESSION SET "_PUSH_JOIN_PREDICATE" = FALSE;
SELECT *
FROM employees e, (
SELECT manager_id FROM employees) v
WHERE e.manager_id = v.manager_id(+) AND e.employee_id = 100;
-- NO_PUSH_PRED 힌트를 사용한다.
SELECT /*+ NO_PUSH_PRED(v) */ *
FROM employees e, (
SELECT manager_id FROM employees) v
WHERE e.manager_id = v.manager_id(+) AND e.employee_id = 100;
[편집] 관련된 정보
- NO_PUSH_PRED 힌트
- _COMPLEX_VIEW_MERGING 파라미터
- _OPTIMIZER_PUSH_PRED_COST_BASED 파라미터
- _OPTIMIZER_COST_BASED_TRANSFORMATION 파라미터
- _UNNEST_SUBQUERY 파라미터