SSISO Community

시소당

드라이빙(Driving) 순서규칙

■ Sort-Merge 의 경우

  -  두 개 컬럼 모두 같은 조건( 인덱스가 둘 다 없거나, 둘 다 있는 경우)인 경우에는 FROM절의
    가장 오른쪽에 정의된 테이블이 구동테이블이 됨.

SQL>select a.empno , a.ename , a.sal, b.deptno, b.dname, b.loc
        from  big_emp a , big_dept b
        where a.deptno = b.deptno
            and b.deptno between 10 and 40
            and b.loc = 'DALLAS' ;

Rows    Execution Plan
-------  ---------------------------------------------------
      0  SELECT STATEMENT  GOAL: CHOOSE
  14728  MERGE JOIN
      4      SORT (JOIN)
      3        TABLE ACCESS (FULL) OF 'BIG_DEPT'  <=  Driving Table
  14728    SORT (JOIN)
  28955      TABLE ACCESS (FULL) OF 'BIG_EMP'  <=  Inner Table


■ Nested-Loop Join 의 경우

- 한쪽 컬럼에만 인덱스가 생성되어 있는 경우에는 FROM절에 열거된 테이블의 순서와는 상관없
  이 인덱스 없는 테이블이 우선순위가 됨
  (Join 문장에는 WHERE 조건절이 없기 때문에 어떤 경우라도 하나의 테이블이 전체스캔 되어야
  하는데 인덱스가 있는 테이블을 구동테이블로 선택시 인덱스를 전체 스캔하고 다시 테이블을 전
  체 스캔을 시켜야 하기 때문에 오히려 인덱스가 없는 테이블을 전체 스캔하는 경우보다 더 많은
  액세스를 할 수 있기 때문)

SQL>create index i_dept_deptno_loc On big_dept(deptno,loc) ;
SQL>select a.empno , a.ename , a.sal, b.deptno, b.dname, b.loc
        from  big_emp a , big_dept b
        where a.deptno = b.deptno
            and b.deptno between 10 and 40
            and b.loc = 'DALLAS' ;

Rows    Row Source Operation
-------  ---------------------------------------------------
  14728  NESTED LOOPS
  28956  TABLE ACCESS FULL BIG_EMP                    <=  InnerTable
  14728  TABLE ACCESS BY INDEX ROWID BIG_DEPT  <= Driving Table
  43683    INDEX RANGE SCAN (object id 27502)

- 조인에 참여되는 공통컬럼 중 한쪽만 인덱스가 생성되어 있고 하나의 비조인 컬럼에 유일 인덱스
  가 생성되어 있는 경우 유일 인덱스를 가진 테이블이 구동 테이블이 된다.
  (Unique Index는 검색방법 중 대단히 좋은 성능을 보장해 주는 Index Type 임)

SQL>create unique index i_emp_empno on big_emp(empno);
SQL>create index i_emp_deptno on big_dept(deptno);
SQL>select  big_emp.ename , big_dept.dname
        from    big_emp,big_dept
        where  big_emp.deptno = big_dept.deptno
            and big_emp.empno = 4000;

Rows    Row Source Operation
-------  ---------------------------------------------------
      1  NESTED LOOPS
      2  TABLE ACCESS BY INDEX ROWID BIG_EMP  <= driving table
      2      INDEX UNIQUE SCAN (object id 27505)
      1  TABLE ACCESS BY INDEX ROWID BIG_DEPT  <= inner table
      2      INDEX RANGE SCAN (object id 27506)

- 조인에 참여하는 공통컬럼이 모두 인덱스가 생성되어 있는 경우 FROM절로 부터 가장 오른쪽에 정
  의된 테이블이 구동테이블.

SQL>create index i_emp_deptnoon on big_emp(deptno);
SQL>create index i_dept_deptno on big_dept(deptno);
SQL>select  big_emp.ename , big_dept.dname
        from    big_emp,big_dept
        where  big_emp.deptno = big_dept.deptno
            and big_emp.empno = 4000 ;

Rows    Row Source Operation
-------  ---------------------------------------------------
      1  NESTED LOOPS
    290  TABLE ACCESS FULL BIG_DEPT                    <= driving table
      1    TABLE ACCESS BY INDEX ROWID BIG_EMP    <= inner table
  18806    INDEX RANGE SCAN (object id 27508)

■ Outer Join 의 경우

- 두 개 이상의 테이블이 공통컬럼을 기준으로 결합될 때 외부키(Foreign-key)를 가진 컬럼 쪽에
  NULL값이 저장되어  있으면 NULL값을 가진 행이 검색 대상에서 제외되는 문제가 발생
  (PIRMARY-KEY를 가진 테이블에는 NULL이라는 식별키의 컬럼이 존재하지 않기 때문)
- Outer Join을 사용하면 외부키에 NULL값이 저장되어 있는 컬럼을 검색대상에 포함
  (NULL값을 가진 테이블 쪽에 (+) 기호 사용)
- OUTER JOIN은 Non-Outer Join TABLE 이 구동 테이블이 됨.

SQL>select  big_emp.ename , big_dept.dname
        from    big_emp,big_dept
        where  big_emp.deptno(+) = big_dept.deptno ;

Rows    Row Source Operation
-------  ---------------------------------------------------
  18756  NESTED LOOPS OUTER
    290  TABLE ACCESS FULL BIG_DEPT                      <= driving table
  18517  TABLE ACCESS BY INDEX ROWID BIG_EMP    <= inner tavle   
  18806    INDEX RANGE SCAN (object id 27508)

2502 view

4.0 stars