2014년 5월 26일 월요일

조인 방법 변경(USE_NL) [ORACLE/SQL/HINT/오라클/교육/강의/강좌/SQL교육/오라클 PLSQL/강의/강좌/오라클교육/ORACLE초보교육/오라클실무강좌] 테이블을 조인 하는 경우 중첩 루프 조인(Nested Loop Join)이 일어나도록 하는 힌트 문장 입니다. 중첩 루프 조인은 중첩 반복이라고도 하는데 하나의 테이블(outer/driving table)에서 추출된 로우를 가지고 일일이 다른 테이블(inner/probed table)을 반복해서 조회하여 찾아지는 레코드를 최종 데이터로 간주하는 방법 입니다. 즉 조인 입력 한 개를 외부 입력 테이블로 사용하고, 한 개는 내부(최하위) 입력 테이블로 사용하고 외부 루프는 외부 입력 테이블을 행 단위로 사용하고 각 외부 행에 대해 실행되는 내부 루프는 내부 입력 테이블에서 일치되는 행을 검색 하는거죠… 이것을 원시 중첩 루프 조인이라고 하는데 검색에서 인덱스를 사용하는 경우에는 인덱스 중첩 루프 조인이라고 합니다. 예를 들어 EMP 테이블과 DEPT 테이블을 조인하는 경우 dept 테이블이 건수가 작다면 우선 이 테이블을 외부 루프로 해서 하나씩 읽으면서 이에 대응하는 emp 테이블의 데이터를 추출 하는 경우라면 중첩 루프 조인에 해당 합니다. 이때 emp 테이블의 경우 건수가 많다고 가정을 하면 대부분 인덱스를 이용하도록 emp 테이블의 외래키인 deptno 컬럼은 대부분 인덱스를 걸게 되죠^^ 중첩 루프 조인은 테이블중 적어도 하나의 조인 컬럼에 대해 인덱스(or Hash Index)가 존재할 때 연관되는 방식으로 이 중첩 루프 조인에서 테이블중 하나의 테이블 또는 중간 결과 셋을 대상으로 FULL SCAN이 일어나게 됩니다. 이 테이블이 드라이빙 테이블이 되는데… 이 테이블의 데이터 건마다 나머지 테이블에서 원하는 데이터를 추출하기 위해 대부분 인덱스를 사용하게 되는 겁니다. 보통 USE_NL 힌트 구문은 ORDERED 힌트 구문과 같이 사용되는데 USE_NL이 취하는 인자는 FROM절에서 두번째 나오는 테이블(비드라이빙 테이블, inner/probed table)을 명시해 주어야 합니다. 안수로 사용되지 않은 첫 번째 테이블은 outer/driving table이 되는 것입니다. [형식] /*+ USE_NL ( table [table]... ) */ [예] 아래는 Oracle 10g에서 테스트 한 결과 입니다. analyze table emp compute statistics analyze table dept compute statistics select /*+ORDERED USE_NLe) */ e.ename, d.dname from dept d, emp e where e.deptno = d.deptno ------------------------------------------------------------ Operation Object Name Rows Bytes Cost --------------------------------------------------------------- SELECT STATEMENT Optimizer Mode=ALL_ROWS 14 4 TABLE ACCESS BY INDEX ROWID SCOTT.EMP 4 32 1 NESTED LOOPS 14 266 4 TABLE ACCESS FULL SCOTT.DEPT 4 44 3 INDEX RANGE SCAN SCOTT.IDX_EMP_DEPTNO 5 0 FROM절에서 처음 나타나는 테이블이 드라이빙 테이블(DRIVING/OUTER TABLE)이며 비드라이빙 테이블(PROBE/INNER TABLE)이 USE_NL의 인자로 들어갑니다!! select /*+ORDERED USE_NL(D) */ e.ename, d.dname from emp e, dept d where e.deptno = d.deptno -------------------------------------------------------------- Operation Object Name Rows Bytes Cost -------------------------------------------------------------- SELECT STATEMENT Optimizer Mode=ALL_ROWS 14 3 NESTED LOOPS 14 266 3 TABLE ACCESS BY INDEX ROWID SCOTT.EMP 14 112 2 INDEX FULL SCAN SCOTT.IDX_EMP_DEPTNO 13 1 TABLE ACCESS BY INDEX ROWID SCOTT.DEPT 1 11 1 INDEX UNIQUE SCAN SCOTT.PK_DEPT 1 0 이번에는 USE_MERGE와 ORDERED가 같이 쓰이는 경우인데 이 경우엔 FROM 절 뒤 테이블의 순서는 실행계획은 다르게 나티날지 모르지만 성능에는 영향을 미치지 않습니다. 왜냐구요? 위 내용을 읽어 보세요!! select /*+ORDERED USE_MERGE(D) */ e.ename, d.dname from emp e, dept d where e.deptno = d.deptno -------------------------------------------------------------- Operation Object Name Rows Bytes Cost ------------------------------------------------------------- SELECT STATEMENT Optimizer Mode=ALL_ROWS 14 6 MERGE JOIN 14 266 6 TABLE ACCESS BY INDEX ROWID SCOTT.EMP 14 112 2 INDEX FULL SCAN SCOTT.IDX_EMP_DEPTNO 13 1 SORT JOIN 4 44 4 TABLE ACCESS FULL SCOTT.DEPT 4 44 3 select /*+ ORDERED USE_MERGE(E) */ e.ename, d.dname from dept D, emp E where e.deptno = d.deptno ---------------------------------------------------------------- Operation Object Name Rows Bytes Cost -------------------------------------------------------------- SELECT STATEMENT Optimizer Mode=ALL_ROWS 14 5 MERGE JOIN 14 266 5 TABLE ACCESS BY INDEX ROWID SCOTT.DEPT 4 44 2 INDEX FULL SCAN SCOTT.PK_DEPT 4 1 SORT JOIN 14 112 3 TABLE ACCESS BY INDEX ROWID SCOTT.EMP 14 112 2 INDEX FULL SCAN SCOTT.IDX_EMP_DEPTNO 13 1 * 이종철님에 의해서 게시물 이동되었습니다 (2006-06-04 12:28) [출처] 오라클자바커뮤니티 - http://www.oraclejavacommunity.co.kr/bbs/board.php?bo_table=LecHINT&wr_id=48 오라클자바커뮤니티교육센터, 개발자전문교육, 개인80%환급 www.oraclejavacommunity.com 평일주간(9:30~18:20) 개강 (5/28)[교육전취업확정]Spring,MyBatis,XPlatform실무프로젝트과정 (5/30)[기업100%환급]자바기초에서 JDBC, Servlet/JSP까지 (5/30)[기업100%환급]SQL기초에서 Schema Object까지 (6/09)[기업100%환급]PL/SQL,ORACLE HINT,TUNING (6/09)[기업100%환급]안드로이드개발자과정 (6/09)[기업100%환급]Spring ,MyBatis,Hibernate실무과정 (6/16)[기업100%환급]C#4.0,WinForm,ADO.NET프로그래밍 평일야간(19:00~21:50) 개강 (5/28)Spring3.X, MyBatis, Hibernate실무과정 (5/28)SQL초보에서실전전문가까지 (5/29)자바기초에서JSP,Ajax,jQuery,Spring3.2,MyBatis까지 (6/03)안드로이드개발자과정 (6/03)웹퍼블리싱 마스터 (6/10)C#4.0, ADO.NET, Network 프로그래밍 (6/19)C#,ASP.NET마스터 주말(10:00~17:50) 개강 (5/31)Spring3.X, MyBatis, Hibernate실무과정 (5/31)자바기초에서JSP,Ajax,jQuery,Spring3.2,MyBatis까지 (5/31)SQL초보에서실전전문가까지 (5/31)C#,ASP.NET마스터 (5/31)실무예제로 배워보는 jQuery(개발자/디자이너를위한) (5/31)안드로이드개발자과정 주말저녁(18:30~22:20) 개강 (6/21)JAVA,Network&WEB&Framework (6/21)SQL기초에서실무까지

조인 방법 변경(USE_NL) [ORACLE/SQL/HINT/오라클/교육/강의/강좌/SQL교육/오라클 PLSQL/강의/강좌/오라클교육/ORACLE초보교육/오라클실무강좌]

테이블을 조인 하는 경우 중첩 루프 조인(Nested Loop Join)이 일어나도록 하는 힌트 문장 입니다. 중첩 루프 조인은 중첩 반복이라고도 하는데 하나의 테이블(outer/driving table)에서 추출된 로우를 가지고 일일이 다른 테이블(inner/probed table)을 반복해서 조회하여 찾아지는 레코드를 최종 데이터로 간주하는 방법 입니다. 

즉 조인 입력 한 개를 외부 입력 테이블로 사용하고, 한 개는 내부(최하위) 입력 테이블로 사용하고 외부 루프는 외부 입력 테이블을 행 단위로 사용하고 각 외부 행에 대해 실행되는 내부 루프는 내부 입력 테이블에서 일치되는 행을 검색 하는거죠…  이것을 원시 중첩 루프 조인이라고 하는데 검색에서 인덱스를 사용하는 경우에는 인덱스 중첩 루프 조인이라고 합니다. 

예를 들어 EMP 테이블과 DEPT 테이블을 조인하는 경우 dept 테이블이 건수가 작다면 우선 이 테이블을 외부 루프로 해서 하나씩 읽으면서 이에 대응하는 emp 테이블의 데이터를 추출 하는 경우라면 중첩 루프 조인에 해당 합니다. 이때 emp 테이블의 경우 건수가 많다고 가정을 하면 대부분 인덱스를 이용하도록 emp 테이블의 외래키인 deptno 컬럼은 대부분 인덱스를 걸게 되죠^^ 
  
중첩 루프 조인은 테이블중 적어도 하나의 조인 컬럼에 대해 인덱스(or Hash Index)가 존재할 때 연관되는 방식으로 이 중첩 루프 조인에서 테이블중 하나의 테이블 또는 중간 결과 셋을 대상으로 FULL SCAN이 일어나게 됩니다. 이 테이블이 드라이빙 테이블이 되는데… 이 테이블의 데이터 건마다 나머지 테이블에서 원하는 데이터를 추출하기 위해 대부분 인덱스를 사용하게 되는 겁니다. 

보통 USE_NL 힌트 구문은 ORDERED 힌트 구문과 같이 사용되는데 USE_NL이 취하는 인자는 FROM절에서 두번째 나오는 테이블(비드라이빙 테이블, inner/probed table)을 명시해 주어야 합니다. 안수로 사용되지 않은 첫 번째 테이블은  outer/driving table이 되는 것입니다. 

[형식] 
/*+ USE_NL ( table [table]... ) */ 


[예] 

아래는 Oracle 10g에서 테스트 한 결과 입니다. 

analyze table emp compute statistics 
analyze table dept compute statistics 

select /*+ORDERED USE_NLe) */ 
      e.ename, 
          d.dname 
from  dept d, emp e 
where  e.deptno = d.deptno        

------------------------------------------------------------ 
Operation        Object Name        Rows        Bytes        Cost        
--------------------------------------------------------------- 
SELECT STATEMENT Optimizer Mode=ALL_ROWS                14                  4 
  TABLE ACCESS BY INDEX ROWID        SCOTT.EMP        4          32          1          
    NESTED LOOPS                14          266          4                                  
      TABLE ACCESS FULL        SCOTT.DEPT        4          44          3                    
      INDEX RANGE SCAN        SCOTT.IDX_EMP_DEPTNO        5                  0  


        FROM절에서 처음 나타나는 테이블이 드라이빙 테이블(DRIVING/OUTER TABLE)이며 비드라이빙 테이블(PROBE/INNER TABLE)이 USE_NL의 인자로 들어갑니다!! 

select /*+ORDERED USE_NL(D) */ 
      e.ename, 
          d.dname 
from  emp e, dept d 
where  e.deptno = d.deptno        

-------------------------------------------------------------- 
Operation        Object Name        Rows        Bytes        Cost        
-------------------------------------------------------------- 
SELECT STATEMENT Optimizer Mode=ALL_ROWS                14                  3 
  NESTED LOOPS                14          266          3                                  
    TABLE ACCESS BY INDEX ROWID        SCOTT.EMP        14          112          2          
      INDEX FULL SCAN        SCOTT.IDX_EMP_DEPTNO        13                  1 
    TABLE ACCESS BY INDEX ROWID        SCOTT.DEPT        1          11          1          
      INDEX UNIQUE SCAN        SCOTT.PK_DEPT        1                  0          
                                                    

이번에는 USE_MERGE와 ORDERED가 같이 쓰이는 경우인데 이 경우엔 FROM 절 뒤 테이블의 순서는 실행계획은 다르게 나티날지 모르지만 성능에는 영향을 미치지 않습니다. 왜냐구요? 위 내용을 읽어 보세요!! 


select /*+ORDERED USE_MERGE(D) */ 
      e.ename, 
          d.dname 
from  emp e, dept d 
where  e.deptno = d.deptno        


-------------------------------------------------------------- 
Operation        Object Name        Rows        Bytes        Cost        
------------------------------------------------------------- 
SELECT STATEMENT Optimizer Mode=ALL_ROWS                14                  6 
  MERGE JOIN                14          266          6                                                      
    TABLE ACCESS BY INDEX ROWID        SCOTT.EMP        14          112          2          
      INDEX FULL SCAN        SCOTT.IDX_EMP_DEPTNO        13                  1 
    SORT JOIN                4          44          4                                                      
      TABLE ACCESS FULL        SCOTT.DEPT        4          44          3                                                      


select /*+ ORDERED USE_MERGE(E) */ 
      e.ename, 
          d.dname 
from  dept D, emp E 
where  e.deptno = d.deptno        


---------------------------------------------------------------- 
Operation        Object Name        Rows        Bytes        Cost        
-------------------------------------------------------------- 
SELECT STATEMENT Optimizer Mode=ALL_ROWS                14                  5 
  MERGE JOIN                14          266          5                                                      
    TABLE ACCESS BY INDEX ROWID        SCOTT.DEPT        4          44          2          
      INDEX FULL SCAN        SCOTT.PK_DEPT        4                  1          
    SORT JOIN                14          112          3                                                      
      TABLE ACCESS BY INDEX ROWID        SCOTT.EMP        14          112          2          
        INDEX FULL SCAN        SCOTT.IDX_EMP_DEPTNO        13                  1        


* 이종철님에 의해서 게시물 이동되었습니다 (2006-06-04 12:28) 

댓글 없음:

댓글 쓰기