by-nc-sa     개발자, DBA가 함께 만들어가는 구루비 지식창고!

5. 조건절 이행




조건절 이행 (Transitive Predicate Generation)
"(A=B) 이고 (B=C) 이면 (A=C) 이다" (의 추론을 통해 새로운 조건절을 내부적으로 생성)
조건절 이행 사례
  • 조인전 필터링을 통해 조인되는 데이터량을 줄일 수 있다
  • 테이블 엑세스를 위한 인덱스 사용을 추가로 고려할 수 있다
 
select * from scott.dept d, scott.emp e
 where e.job = 'MANAGER'
   and e.deptno = 10
   and d.deptno = e.deptno
"(e.deptno = 10) 이고 (d.deptno = e.deptno) 이면 (d.deptno = 10) 이다"
 
--------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |      1 |        |      1 |00:00:00.01 |      10 |
|   1 |  NESTED LOOPS                |         |      1 |      1 |      1 |00:00:00.01 |      10 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |      1 |      1 |      1 |00:00:00.01 |       2 |
|*  3 |    INDEX UNIQUE SCAN         | PK_DEPT |      1 |      1 |      1 |00:00:00.01 |       1 |
|*  4 |   TABLE ACCESS FULL          | EMP     |      1 |      1 |      1 |00:00:00.01 |       8 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("D"."DEPTNO"=10)
   4 - filter(("E"."JOB"='MANAGER' AND "E"."DEPTNO"=10))
조건절 이행 사례 (테스트)
 
select * from scott.dept d, scott.emp e
 where e.job = 'MANAGER'
   and e.deptno = 10
   and d.deptno = 10
 
--------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |      1 |        |      1 |00:00:00.01 |      10 |
|   1 |  NESTED LOOPS                |         |      1 |      1 |      1 |00:00:00.01 |      10 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |      1 |      1 |      1 |00:00:00.01 |       2 |
|*  3 |    INDEX UNIQUE SCAN         | PK_DEPT |      1 |      1 |      1 |00:00:00.01 |       1 |
|*  4 |   TABLE ACCESS FULL          | EMP     |      1 |      1 |      1 |00:00:00.01 |       8 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("D"."DEPTNO"=10)
   4 - filter(("E"."JOB"='MANAGER' AND "E"."DEPTNO"=10))
조건절 안이행 사례
정확한 비용 계산을 위해 필터 조건이 추가되고, 조인 조건이 제거 되었다. 이로 인해 부작용이 생긴다면 ?
 
select * from scott.dept d, scott.emp e
 where e.job = 'MANAGER'
   and e.deptno = 10
   and d.deptno = e.deptno + 0
 
--------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |      1 |        |      1 |00:00:00.01 |      10 |
|   1 |  NESTED LOOPS                |         |      1 |        |      1 |00:00:00.01 |      10 |
|   2 |   NESTED LOOPS               |         |      1 |      1 |      1 |00:00:00.01 |       9 |
|*  3 |    TABLE ACCESS FULL         | EMP     |      1 |      1 |      1 |00:00:00.01 |       8 |
|*  4 |    INDEX UNIQUE SCAN         | PK_DEPT |      1 |      1 |      1 |00:00:00.01 |       1 |
|   5 |   TABLE ACCESS BY INDEX ROWID| DEPT    |      1 |      1 |      1 |00:00:00.01 |       1 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(("E"."JOB"='MANAGER' AND "E"."DEPTNO"=10))
   4 - access("D"."DEPTNO"="E"."DEPTNO"+0)
조건절 이행 좋은 사례
create table 상품이력 (상품번호 number, 시작일자 varchar2(8), 종료일자 varchar2(8));
create table 주문 (거래일자 varchar2(8), 상품번호 number);
select *
  from 상품이력 a, 주문 b
 where b.거래일자 between '20090101' and '20090131'
   and a.상품번호 = b.상품번호
   and b.거래일자 between a.시작일자 and a.종료일자
select *
  from 상품이력 a, 주문 b
 where b.거래일자 >= '20090101'
   and b.거래일자 <= '20090131'
   and a.상품번호 = b.상품번호
   and b.거래일자 >= a.시작일자
   and b.거래일자 <= a.종료일자;
"(b.거래일자 >= '20090101') 이고 (b.거래일자 <= a.종료일자) 이면 ('20090101' <= a.종료일자) 이다"
"(b.거래일자 <= '20090131') 이고 (b.거래일자 >= a.시작일자) 이면 ('20090131' >= a.시작일자) 이다"

----------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |      0 |00:00:00.01 |       3 |       |       |          |
|*  1 |  HASH JOIN         |      |      1 |      1 |      0 |00:00:00.01 |       3 |   904K|   904K|  186K (0)|
|*  2 |   TABLE ACCESS FULL| 상품 |      1 |      1 |      0 |00:00:00.01 |       3 |       |       |          |
|*  3 |   TABLE ACCESS FULL| 주문 |      0 |      1 |      0 |00:00:00.01 |       0 |       |       |          |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("A"."상품번호"="B"."상품번호")
       filter(("B"."거래일자">="A"."시작일자" AND "B"."거래일자"<="A"."종료일자"))
   2 - filter(("A"."종료일자">='20090101' AND "A"."시작일자"<='20090131'))
   3 - filter(("B"."거래일자">='20090101' AND "B"."거래일자"<='20090131'))
select *
  from 상품이력 a, 주문 b
 where b.거래일자 between '20090101' and '20090131'
   and a.상품번호 = b.상품번호
   and b.거래일자 between a.시작일자 and a.종료일자
   and a.시작일자 <= '20090131'
   and a.종료일자 >= '20090101'

----------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |      0 |00:00:00.01 |       3 |       |       |          |
|*  1 |  HASH JOIN         |      |      1 |      1 |      0 |00:00:00.01 |       3 |   904K|   904K|  186K (0)|
|*  2 |   TABLE ACCESS FULL| 상품 |      1 |      1 |      0 |00:00:00.01 |       3 |       |       |          |
|*  3 |   TABLE ACCESS FULL| 주문 |      0 |      1 |      0 |00:00:00.01 |       0 |       |       |          |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("A"."상품번호"="B"."상품번호")
       filter(("B"."거래일자">="A"."시작일자" AND "B"."거래일자"<="A"."종료일자"))
   2 - filter(("A"."시작일자"<='20090131' AND "A"."종료일자">='20090101'))
   3 - filter(("B"."거래일자">='20090101' AND "B"."거래일자"<='20090131'))
튜닝 사례 1
CREATE IP주소목록_PK ON IP주소목록(IP주소)
CREATE IP주소목록_X01 ON IP주소목록(시작IP주소)
SELECT IP주소, IP연결일자, 시작IP주소, 종료IP주소
     , ISP명, IP등록일자, IP사용기관ID, IP사용기관명, IP사용시도명
     , 사용기관주소, 사용기관우편번호, IP책임자명, IP책임자전화번호
  FROM IP주소목록
 WHERE 시작IP주소 >= :strtIpAddr
   AND 종료IP주소 <= :endIpAddr

-- 192.168.000 서브넷에 속한 IP주소 목록을 가져오기
 :strtIpAddr := '192.168.000.001'
 :endIpAddr  := '192.168.000.255'
Call     Count  CPU Time Elapsed Time      Disk      Query    Current        Rows
------- ------  -------- ------------ ---------- ---------- ----------  ----------
Parse        1     0.000         0.00          0          0          0           0
Execute      1     0.000         0.00          0          0          0           0
Fetch        9    32.820     1922.797     341291    6940276          0         106
------- ------  -------- ------------ ---------- ---------- ----------  ----------
Total       11    32.820     1922.797     341291    6940276          0         106

Rows    Row Source Operation
------- ----------------------------------------------------
    106 TABLE ACCESS BY INDEX ROWID IP주소목록 (cr=6940276 pr=341291 pw=0 ... )
8362619  INDEX RANGE SCAN IP주소목록_X01 (cr=27980 pr=27968 pw=0 time=33450495 us)
인덱스 읽고 테이블 액세스 : 8,362,619 회
테이블 랜덤 엑세스 : 6,912,296 (= 6,940,276 - 27,980) 회

-- IP주소목록_X01 인덱스에 종료IP주소 컬럼 추가?
---- 현재 인덱스 스캔도 무리

-- 우리만 아는 정보 적용
SELECT IP주소, IP연결일자, 시작IP주소, 종료IP주소
     , ISP명, IP등록일자, IP사용기관ID, IP사용기관명, IP사용시도명
     , 사용기관주소, 사용기관우편번호, IP책임자명, IP책임자전화번호
  FROM IP주소목록
 WHERE 시작IP주소 >= :strtIpAddr  -- ①
   AND 종료IP주소 <= :endIpAddr   -- ②
   AND 시작IP주소 <= 종료IP주소   -- ③

-- ①, ②, ③ 합성
:strtIpAddr <= 시작IP주소 <= 종료IP주소 <= :endIpAddr

-- 시작IP주소, 종료IP주소 컬럼 기준으로 다시 분해
 WHERE 시작IP주소 BETWEEN :strtIpAddr AND :endIpAddr
   AND 종료IP주소 BETWEEN :strtIpAddr AND :endIpAddr

-- 변수 바인딩
 WHERE 시작IP주소 BETWEEN '192.168.000.001' AND '192.168.000.255' 
   AND 종료IP주소 BETWEEN '192.168.000.001' AND '192.168.000.255' 
SELECT IP주소, IP연결일자, 시작IP주소, 종료IP주소
     , ISP명, IP등록일자, IP사용기관ID, IP사용기관명, IP사용시도명
     , 사용기관주소, 사용기관우편번호, IP책임자명, IP책임자전화번호
  FROM IP주소목록
 WHERE 시작IP주소 BETWEEN :strtIpAddr AND :endIpAddr
   AND 종료IP주소 BETWEEN :strtIpAddr AND :endIpAddr

-- 192.168.000 서브넷에 속한 IP주소 목록을 가져오기
 :strtIpAddr := '192.168.000.001'
 :endIpAddr  := '192.168.000.255'
Call     Count  CPU Time Elapsed Time      Disk      Query    Current        Rows
------- ------  -------- ------------ ---------- ---------- ----------  ----------
Parse        1     0.000        0.000          0          0          0           0
Execute      1     0.000        0.000          0          0          0           0
Fetch        9     0.000        0.001          0         55          0         106
------- ------  -------- ------------ ---------- ---------- ----------  ----------
Total       11     0.000        0.001          0         55          0         106

Rows    Row Source Operation
------- ----------------------------------------------------
      0 STATEMENT
    106  FILTER (cr=55 pr=0 pw=0 time=37 us)
    106   TABLE ACCESS BY INDEX ROWID IP주소목록 (cr=55 pr=0 pw=0 time=34 us)
    106    INDEX RANGE SCAN IP주소목록_X01 (cr=12 pr=0 pw=0 time=654 us)
튜닝 사례 2
drop table 고객;
drop table 주문;
drop table 주문상세;

create table 고객 (고객번호 number, 고객명 varchar2(10));
create table 주문 (주문일자 varchar2(8), 주문번호 number, 고객번호 number, 배송지 varchar2(100));
create table 주문상세 (주문일자 varchar2(8), 주문번호 number, 고객번호 number, 상품번호 number, 상품가격 number, 주문수량 number);

alter table 고객 add constraint 고객_PK primary key (고객번호);
alter table 주문 add constraint 주문_PK primary key (주문일자, 주문번호);
alter table 주문상세 add constraint 주문상세_PK primary key (주문일자, 주문번호, 상품번호);

alter table 주문 add constraint 주문_FK_고객 foreign key (고객번호) references 고객 (고객번호);
alter table 주문상세 add constraint 주문상세_FK_주문 foreign key (주문일자, 주문번호) references 주문 (주문일자, 주문번호);

insert into 고객
select rownum as 고객번호, dbms_random.string('X', 10) as 고객명 from dual connect by level <= 10;

insert into 주문   
select x.주문일자,
       rank() over (partition by x.주문일자 order by rownum) as 주문번호,
       x.고객번호,
       x.배송지
  from (    
select to_char(sysdate + round(dbms_random.value(1, 100)), 'YYYYMMDD') as 주문일자,
       a.고객번호,
       dbms_random.string('X', 100) as 배송지
  from 고객 a, (select level from dual connect by level <= 100)
       ) x;

insert into 주문상세
select a.주문일자, a.주문번호, a.고객번호,
       round(dbms_random.value(1111111,9999999)) as 상품번호, 
       round(dbms_random.value(10000,99999)) as 상품가격, 
       round(dbms_random.value(1,99)) as 주문수량
  from 주문 a, (select level from dual connect by level <= 10);
  
commit;

exec dbms_stats.gather_table_stats (ownname => 'uadmin', tabname => '고객' , degree => 1, cascade => TRUE);
exec dbms_stats.gather_table_stats (ownname => 'uadmin', tabname => '주문' , degree => 1, cascade => TRUE);
exec dbms_stats.gather_table_stats (ownname => 'uadmin', tabname => '주문상세' , degree => 1, cascade => TRUE);
쿼리1 (ORDERED 로 강제한 조인 순서와 조인문이 조화로움) 쿼리2 (ORDERED 로 강제한 조인 순서와 조인문이 불량스러움, 조인문 자체는 전이되지 않는다)
select /*+ gather_plan_statistics ordered use_nl(o) use_nl(d) index(o) index(d) */
       c.고객명, o.주문일자, o.주문번호, o.배송지, d.상품번호, d.상품가격, d.주문수량
  from 고객 c, 주문 o, 주문상세 d
 where o.고객번호 = c.고객번호
   and d.고객번호 = o.고객번호
   and d.주문일자 = o.주문일자
   and d.주문번호 = o.주문번호
   and d.주문일자 = to_char(sysdate + 1, 'YYYYMMDD');

select /*+ gather_plan_statistics ordered use_nl(o) use_nl(d) index(o) index(d) */
       c.고객명, o.주문일자, o.주문번호, o.배송지, d.상품번호, d.상품가격, d.주문수량
  from 고객 c, 주문 o, 주문상세 d
 where d.고객번호 = c.고객번호
   and d.고객번호 = o.고객번호
   and d.주문일자 = o.주문일자
   and d.주문번호 = o.주문번호
   and d.주문일자 = to_char(sysdate + 1, 'YYYYMMDD');   

----------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |         |      1 |        |     90 |00:00:00.01 |     145 |
|   1 |  NESTED LOOPS                  |         |      1 |        |     90 |00:00:00.01 |     145 |
|   2 |   NESTED LOOPS                 |         |      1 |      2 |     90 |00:00:00.01 |      56 |
|   3 |    NESTED LOOPS                |         |      1 |      2 |      9 |00:00:00.01 |      38 |
|   4 |     TABLE ACCESS FULL          | 고객    |      1 |     10 |     10 |00:00:00.01 |      13 |
|*  5 |     TABLE ACCESS BY INDEX ROWID| 주문    |     10 |      1 |      9 |00:00:00.01 |      25 |
|*  6 |      INDEX RANGE SCAN          | 주문_PK |     10 |      2 |     90 |00:00:00.01 |      18 |
|*  7 |    INDEX RANGE SCAN            | 주문상세|      9 |      1 |     90 |00:00:00.01 |      18 |
|*  8 |   TABLE ACCESS BY INDEX ROWID  | 주문상세|     90 |      1 |     90 |00:00:00.01 |      89 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   5 - filter("O"."고객번호"="C"."고객번호")
   6 - access("O"."주문일자"=TO_CHAR(SYSDATE@!+1,'YYYYMMDD'))
   7 - access("D"."주문일자"=TO_CHAR(SYSDATE@!+1,'YYYYMMDD') AND "D"."주문번호"="O"."주문번호")
   8 - filter("D"."고객번호"="O"."고객번호")

----------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |         |      1 |        |     90 |00:00:00.01 |     937 |
|   1 |  NESTED LOOPS                  |         |      1 |        |     90 |00:00:00.01 |     937 |
|   2 |   NESTED LOOPS                 |         |      1 |      2 |    900 |00:00:00.01 |      57 |
|   3 |    NESTED LOOPS                |         |      1 |     20 |     90 |00:00:00.01 |      38 |
|   4 |     TABLE ACCESS FULL          | 고객    |      1 |     10 |     10 |00:00:00.01 |      13 |
|   5 |     TABLE ACCESS BY INDEX ROWID| 주문    |     10 |      2 |     90 |00:00:00.01 |      25 |
|*  6 |      INDEX RANGE SCAN          | 주문_PK |     10 |      2 |     90 |00:00:00.01 |      18 |
|*  7 |    INDEX RANGE SCAN            | 주문상세|     90 |      1 |    900 |00:00:00.01 |      19 |
|*  8 |   TABLE ACCESS BY INDEX ROWID  | 주문상세|    900 |      1 |     90 |00:00:00.01 |     880 |
----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   6 - access("O"."주문일자"=TO_CHAR(SYSDATE@!+1,'YYYYMMDD'))
   7 - access("D"."주문일자"=TO_CHAR(SYSDATE@!+1,'YYYYMMDD') AND "D"."주문번호"="O"."주문번호")
   8 - filter(("D"."고객번호"="C"."고객번호" AND "D"."고객번호"="O"."고객번호"))
  • 힌트에 의해 고객→주문→주문상세 순으로 NL 조인된다
  • Id(5) 에서 filter("O"."고객번호"="C"."고객번호") 로 범위를 줄였다
  • 고객번호에 대한 조인이 주문, 주문상세 테이블 엑세스 단계 에서 나타난다
  • 힌트에 의해 고객→주문→주문상세 순으로 NL 조인된다
  • Id(5) 에서 범위를 못줄였다, 비록 (주문상세.고객번호 = 고객.고객번호 and 주문상세.고객번호 = 주문.고객번호) 조건이 있으나, 조인문은 전이되지 않음
  • 고객번호에 대한 조인이 주문상세 테이블 엑세스 단계 에서만 나타난다
Undocumented OVERLAPS Function

-- 준비
CREATE TABLE T AS
SELECT '강철중' AS NAME, TO_DATE('2010-10-01', 'YYYY-MM-DD') AS 휴가시작, TO_DATE('2010-10-03', 'YYYY-MM-DD') AS 휴가종료 FROM DUAL
UNION ALL
SELECT '강감찬' AS NAME, TO_DATE('2010-10-04', 'YYYY-MM-DD') AS 휴가시작, TO_DATE('2010-10-06', 'YYYY-MM-DD') AS 휴가종료 FROM DUAL
UNION ALL
SELECT '이순신' AS NAME, TO_DATE('2010-10-06', 'YYYY-MM-DD') AS 휴가시작, TO_DATE('2010-10-08', 'YYYY-MM-DD') AS 휴가종료 FROM DUAL
UNION ALL
SELECT '유관순' AS NAME, TO_DATE('2010-10-09', 'YYYY-MM-DD') AS 휴가시작, TO_DATE('2010-10-12', 'YYYY-MM-DD') AS 휴가종료 FROM DUAL
UNION ALL
SELECT '오화균' AS NAME, TO_DATE('2010-10-02', 'YYYY-MM-DD') AS 휴가시작, TO_DATE('2010-10-05', 'YYYY-MM-DD') AS 휴가종료 FROM DUAL

CREATE INDEX T_PK ON T (NAME);
CREATE INDEX T_N1 ON T (휴가시작);
CREATE INDEX T_N2 ON T (휴가종료);

exec dbms_stats.gather_table_stats (ownname => 'uadmin', tabname => 'T' , degree => 1, cascade => TRUE);
SELECT /*+ gather_plan_statistics */ * FROM T 
 WHERE (휴가시작, 휴가종료) OVERLAPS (TO_DATE('2010-10-05', 'YYYY-MM-DD'), TO_DATE('2010-10-07', 'YYYY-MM-DD'));

강감찬 10/10/04 10/10/06
이순신 10/10/06 10/10/08

------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |      2 |00:00:00.01 |       8 |
|*  1 |  TABLE ACCESS FULL| T    |      1 |      1 |      2 |00:00:00.01 |       8 |
------------------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
      DB_VERSION('11.2.0.1')
      OPT_PARAM('optimizer_index_cost_adj' 25)
      OPT_PARAM('optimizer_index_caching' 90)
      FIRST_ROWS(10)
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "T"@"SEL$1")
      END_OUTLINE_DATA
  */

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter((INTERNAL_FUNCTION("휴가시작"),INTERNAL_FUNCTION("휴가종료"))OVERLAPS(
              TO_DATE(' 2010-10-05 00:00:00', 'syyyy-mm-dd hh24:mi:ss'),TO_DATE('
              2010-10-07 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
SELECT /*+ gather_plan_statistics */ * FROM T T1, T T2 
 WHERE (T1.휴가시작, T1.휴가종료) OVERLAPS (T2.휴가시작, T2.휴가종료)
   AND T1.NAME <> T2.NAME;

강철중 10/10/01 10/10/03 오화균 10/10/02 10/10/05
강감찬 10/10/04 10/10/06 오화균 10/10/02 10/10/05
오화균 10/10/02 10/10/05 강철중 10/10/01 10/10/03
오화균 10/10/02 10/10/05 강감찬 10/10/04 10/10/06

-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |      4 |00:00:00.01 |      43 |
|   1 |  NESTED LOOPS      |      |      1 |      1 |      4 |00:00:00.01 |      43 |
|   2 |   TABLE ACCESS FULL| T    |      1 |      5 |      5 |00:00:00.01 |       8 |
|*  3 |   TABLE ACCESS FULL| T    |      5 |      1 |      4 |00:00:00.01 |      35 |
-------------------------------------------------------------------------------------

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
      DB_VERSION('11.2.0.1')
      OPT_PARAM('optimizer_index_cost_adj' 25)
      OPT_PARAM('optimizer_index_caching' 90)
      FIRST_ROWS(10)
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "T1"@"SEL$1")
      FULL(@"SEL$1" "T2"@"SEL$1")
      LEADING(@"SEL$1" "T1"@"SEL$1" "T2"@"SEL$1")
      USE_NL(@"SEL$1" "T2"@"SEL$1")
      END_OUTLINE_DATA
  */

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(((INTERNAL_FUNCTION("T1"."휴가시작"),INTERNAL_FUNCTION("T1"."휴가종료")
              )OVERLAPS(INTERNAL_FUNCTION("T2"."휴가시작"),INTERNAL_FUNCTION("T2"."휴가종료")) AND
              "T1"."NAME"<>"T2"."NAME"))


이 문서의 내용은 (주)비투엔컬설팅에서 출간한 '오라클 성능 고도화 원리와 해법II'를 참고하였습니다.
이 문서의 내용은 (주)오픈메이드컨설팅에서 출간한 'THE LOGICAL OPTIMIZER'를 참고하였습니다.

문서정보

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.