2.9 TP* (Transitive Predicate) : 조인절을 이용하여 다른 테이블에 상수조건을 생성시켜라

  • TP(Transitive Predicate or Transitive Closure) : 조인조건을 이용한 조건절 전이
  • TEST Version : Oracle 11.0.3
{code:SQLtitle= 0. 예제borderStyle=solid}
SELECT /*+ gather_plan_statistics */
e.*
FROM employee e, department d
WHERE e.department_id = d.department_id --DEPARTMENT_ID로 조인
AND e.department_id = 50; --d.department_id ='50'으로 바꾸어도 논리적으로 지장이없다.

select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));




























IdOperationNameStartsE-RowsA-RowsA-TimeBuffers




























0SELECT STATEMENT14500:00:00.0114
1NESTED LOOPS1454500:00:00.0114
  • 2
INDEX UNIQUE SCANDEPT_ID_PK11100:00:00.011
3TABLE ACCESS BY INDEX ROWIDEMPLOYEE1454500:00:00.0113
  • 4
INDEX RANGE SCANEMP_DEPARTMENT_IX1454500:00:00.016




























Predicate Information (identified by operation id):













---

2 - access("D"."DEPARTMENT_ID"=50)
4 - access("E"."DEPARTMENT_ID"=50)


Predicate Information에 (D.DEPARTMENT_ID=50)조건 생성|
|{code:SQL|title= 1. 변환된 SQL |borderStyle=solid}
SELECT /*+ gather_plan_statistics */
       e.*
  FROM employee e, department d
 WHERE e.department_id = d.department_id
   AND e.department_id = '50'
   AND d.department_id='50';

2. 10053 Trace정보


**************************
Predicate Move-Around (PM)
**************************
PM:     PM bypassed: Outer query contains no views.
PM:     PM bypassed: Outer query contains no views.
query block SEL$1 (#0) unchanged
FPD: Considering simple filter push in query block SEL$1 (#0)
"E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID" AND "E"."DEPARTMENT_ID"=50
try to generate transitive predicate from check constraints for query block SEL$1 (#0)
finally: "E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID" AND "E"."DEPARTMENT_ID"=50 AND "D"."DEPARTMENT_ID"=50

FPD:   transitive predicates are generated in query block SEL$1 (#0)
"E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID" AND "E"."DEPARTMENT_ID"=50 AND "D"."DEPARTMENT_ID"=50 --D.DEPARTMENT_ID=50조건이 추가적으로 생성

|

  • _optimizer_transitivity_retain를 False로 적용할 경우 Join절이 없어진다.
    ※ _optimizer_transitivity_retain : Transitive Closure에 의해 조인 조건이 없어지는 현상의 방지여부 지정
    {code:SQL
title= _optimizer_transitivity_retain를 False로 적용borderStyle=solid}
ALTER SESSION SET "_optimizer_transitivity_retain" = FALSE;

ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';

select /*+ gather_plan_statistics */
e.EMPLOYEE_ID, e.EMAIL, e.HIRE_DATE
from EMPLOYEE e, DEPARTMENT d
where e.DEPARTMENT_ID = d.DEPARTMENT_ID
and e.DEPARTMENT_ID = '50'

ALTER SESSION SET EVENTS '10053 trace name context off';

**************************
Predicate Move-Around (PM)
**************************
PM: PM bypassed: Outer query contains no views. -->PM실패 no views
PM: PM bypassed: Outer query contains no views.
query block SEL$1 (#0) unchanged
FPD: Considering simple filter push in query block SEL$1 (#0)
"E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID" AND "E"."DEPARTMENT_ID"=50 -->조인조건이 존재함
try to generate transitive predicate from check constraints for query block SEL$1 (#0)
finally: "D"."DEPARTMENT_ID"=50 AND "E"."DEPARTMENT_ID"=50 -->조인절이 없어지고 상수 조건만 존재


|* 주의사항
Operator Transformation이나 Tansive Predicate는 PM(Predicate Move Around)이 아니다.
Predicate Move-Around(PM)자리에 Transitive Predicate가 발생했지만 PM은 발생하지 않았다.(no view) (2.15장에서 설명)
PM은 2.15장에서 자세히 설명|