2016년 10월 11일 화요일

[오라클교육,SQL교육,실무교육은★탑크리에듀★][중첩루프조인 작동방식]

[중첩루프조인 작동방식]

중첩루프조인(Nested Loop Join)

n  부분 범위처리에 유리한 조인 방식으로 두 개 이상의 테이블에서 하나의 테이블(Driving/Outer Table)을 기준으로 순차적으로 다른 테이블(Driven/Inner Table) ROW(RECORD, )를 조인하여 원하는 데이터를 추출하는 방식의 조인이다부분범위 처리시에 사용하며 확실히 범위를 줄여 줄 조건들이 있을 때 사용하는 것이 좋다.
n  추출되는 ROW가 많아 질수록 성능이 현저히 떨어지며 성능을 높이기 위해서는 Driving Table의 크기가 작을수록 유리하며 Inner Table의 조인되는 칼럼은 인덱스가 생성 되어 있어야 한다. (대부분 조인되는 칼럼은 외래키 칼럼이다.)
n  Inner Table에서 인덱스를 사용한다면 검색 알고리즘을 적용할 수도 있으며 한번 읽혀진 블록은 DataBase Buffer Cache에 남겨져 있기에 반복적인 I/O양은 최소화 될 수 있다만약 Inner Table의 크기가 작다면 메모리에 올려서 검색하는 것이 좋지만 현실적으로 대용량의 데이터 처리에서는 어렵다.
n  Nested Loop join에서는 Inner Table을 대체로 인덱스에 의한 랜덤 액세스에 의해 접근하므로 랜덤 액세스 되는  ROW가 많다면 수행속도가 저하된다만약 Inner Table Join 칼럼에 인덱스가 없다면 Hash or Merge Join을 이용해야 한다또한 Inner Table에서 조인 컬럼은 Unique Column 일수록  성능이 좋다.
n  Driving Table 인덱스 액세스의 경우 첫 번째 매칭되는 데이터를 제외하면 나머지 데이터는 한 건씩 스캔 한다.
n  조인방향에 다라 인덱스가 선택적으로 사용된다.
n  주어진 상수 값에 의해 범위가 줄어드는 것은 아니며 값을 받아 처리 범위를 결정하며 조인 후 마지막 체크되는 조건은 수행속도에 영향을 준다.
n  Driving Table이 대량이거나 Inner Table에서 조인되는 데이터가 대량인 경우 Sort Merge 또는 Hash Join을 검토해야 한다.

다음과 같은 SQL을 생각해 보자.

Emp table deptno 칼럼,  Dept table deptno 컬럼은 인덱스 존재

Select /*+ ordered use_nl(e) */
e.ename, e.deptno, d.dname
 From  dept d, emp e                 //dept 테이블이 드라이빙 테이블
Where  e.deptno = d.deptno
and e.job = ‘CLERK’
and d.deptno in (10, 20 ,30)
and d.loc like ‘서울%

-----------------------------------------------------------------------------------------
| Id  | Operation                     | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |         |     1 |    33 |     5   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                 |         |     1 |    33 |     5   (0)| 00:00:01 |
|   2 |   INLIST ITERATOR             |         |       |       |            |          |
|*  3 |    TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    18 |     2   (0)| 00:00:01 |
|*  4 |     INDEX UNIQUE SCAN         | PK_DEPT |     3 |       |     1   (0)| 00:00:01 |
|*  5 |   TABLE ACCESS FULL           | EMP     |     1 |    15 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

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

   3 - filter("D"."LOC" LIKE '서울%')
   4 - access("D"."DEPTNO"=10 OR "D"."DEPTNO"=20 OR "D"."DEPTNO"=30)
   5 - filter("E"."JOB"='CLERK' AND ("E"."DEPTNO"=10 OR "E"."DEPTNO"=20 OR
              "E"."DEPTNO"=30) AND "E"."DEPTNO"="D"."DEPTNO")


[처리순서]

1.       Dept deptno 인덱스를 경유하여 deptno in (10, 20 , 30)인 데이터를 인덱스 범위(index range)추출 후

2.    처음 ROW Access

3.       Dept deptno인덱스의 ROWID를 이용하여 dept 테이블의 원본데이터 추출 후 loc값을 찾아 상수 값으로 두고이 값을 통해 d.loc = ‘서울%’인지 확인 후 맞으면 다음 수행 아니면 2에서 다음 ROW 추출

4.       e.deptno = d.deptno를 수행한다현재 d.deptno 10이므로 상수 처리되어 e.deptno =10인 모양이 되어 아래 쿼리 형태로 실행된다.

SELECT  /*+ ordered use_nl(e) */
e.ename, e.deptno, d.dname
FROM   dept d, emp e                 //dept 테이블이 드라이빙 테이블
WHERE  e.deptno = 10  ß 상수처리

EMP 테이블의 데이터 추출 후 job=CLERK’인지 확인하여 맞으면 추출 아니면 버림

5. 2부터 다시 시작

댓글 없음:

댓글 쓰기