2013년 8월 3일 토요일

[Oracle SQL Tuning]ACCESS 경로를 변경하는 힌트(HASH) - 오라클힌트 이론 실습

ACCESS 경로를 변경하는 힌트(HASH)

구로디지털 오엔제이프로그래밍실무교육센터


인자로 기술한 테이블에 대해 HASH SCAN이 일어나도록 하는 힌트이며 USE_HASH(해시 조인이 일어나도록 하는 힌트)와 구별되며 HASHKEYS parameter를 가지고 만들어진 CLUSTER내에 저장된 테이블에서만 적용 됩니다.

[형식]
/*+ HASH ( table ) */

[]
[먼저 클러스터를 생성]
CREATE CLUSTER MYEMP2_MYDEPT2_CLUSTER (deptno NUMBER(1))
HASH IS deptno HASHKEYS 150;
  

[실습 테이블을 만들면서 클러스터 저장하기 위해 옵션 정의]
   CREATE TABLE MYDEPT2 (
      deptno NUMBER(1) PRIMARY KEY,
  dname  VARCHAR2(100) NOT NULL)
   CLUSTER MYEMP2_MYDEPT2_CLUSTER (deptno);
  
  
   CREATE TABLE MYEMP2 (
          empno  NUMBER PRIMARY KEY,
         ename  VARCHAR2(100) NOT NULL,
         sal    NUMBER(9),
         deptno NUMBER(1) NOT NULL)
   CLUSTER MYEMP2_MYDEPT2_CLUSTER (deptno);




[테스트를 위한 데이터를 만듭니다.]


insert into mydept2 values (0, '인사팀');
 insert into mydept2 values (1, '회계팀');
 insert into mydept2 values (2, '영업팀');
 insert into mydept2 values (3, '기획팀');
 insert into mydept2 values (4, '교육팀');


commit;


DECLARE
          v_c NUMBER := 1;
BEGIN

          WHILE (v_c <= 10000000) LOOP
                insert into myemp2 values ( v_c, '홍길동'||v_c, mod(v_c, 5), '서울'||v_c, mod(v_c, 1000000));
                v_c := v_c + 1;
                insert into myemp2 values ( v_c, '다길동'||v_c, mod(v_c, 5), '부산'||v_c, mod(v_c, 1000000));
                v_c := v_c + 1;
                insert into myemp2 values ( v_c, '나길동'||v_c, mod(v_c, 5), '대구'||v_c, mod(v_c, 1000000));
                v_c := v_c + 1;
                insert into myemp2 values ( v_c, '나길동'||v_c, mod(v_c, 5), '광주'||v_c, mod(v_c, 1000000));
                v_c := v_c + 1;
          END LOOP;
          commit;
END;



  
클러스터 인덱스 만들기 전에 일반 인덱스로 먼저 테스트 해보자.
(무지 느리자)

sQL> create index idx_myemp2_deptno on myemp2(deptno)

SQL> SELECT  /*+ index( E idx_myemp2_dept) */
  2             Count(e.ename)
  3     FROM    MYEMP2 E, MYDEPT2 D
  4     WHERE   D.deptno = E.deptno;

COUNT(E.ENAME)
--------------
      10000000

   : 00:01:15.29

Execution Plan
----------------------------------------------------------
|   0 | SELECT STATEMENT       |              |     1 |    26 |     3   (0)|
|   1 |  SORT AGGREGATE        |              |     1 |    26 |            |
|   2 |   NESTED LOOPS         |              |     1 |    26 |     3   (0)|
|   3 |    INDEX FAST FULL SCAN| SYS_C0011304 |     1 |    13 |     2  
|*  4 |    TABLE ACCESS HASH   | MYEMP2       |  2050K|    25M|     1  




이번엔 HASH SCAN 위한 힌트를 사용해 보자.
조금 빨라졌다.

SQL> SELECT 
  2             count(E.ename)
  3     FROM    MYEMP2 E, MYDEPT2 D
  4     WHERE   D.deptno = E.deptno;

COUNT(E.ENAME)
--------------
      10000000

   : 00:01:01.54

Execution Plan
----------------------------------------------------------
|   0 | SELECT STATEMENT       |              |     1 |    26 |     3   (0)|
|   1 |  SORT AGGREGATE        |              |     1 |    26 |            |
|   2 |   NESTED LOOPS         |              |     1 |    26 |     3   (0)|
|   3 |    INDEX FAST FULL SCAN| SYS_C0011304 |     1 |    13 |     2  
|*  4 |    TABLE ACCESS HASH   | MYEMP2       |  2050K|    25M|     1  



Oracle 11g에서 테스트 했을 때 위의 경우 NESTEDD LOOP로 풀리며 또는 힌트를 사용하지 않더라도 EMP TABLE HASH SCAN을 하는 것으로 나타났습니다.

CLUSTER를 확인 할 수 있는 VIEW는 다음과 같구요,

DBA_CLUSTERS         ALL_CLUSTERS         USER_CLUSTERS

아래에 간단한 HASH CLUSTER TABLE에 대한 설명이 있으니 참고 하세요~

다량의 범위를 자주 엑세스해야 하는 경우나 인덱스를 사용한 처리가 부담이 되는 범위(넓은 분포도), 수정이 자주 발생하지 않는 Column, 대규모 테이블, 여러 개의 테이블이 빈번한 조인을 일으킬 때 CLUSTER INDEX를 사용하시면 되는데 HASH CLUSTER에 테이블을 저장하는 것은 데이타 검색의 성능을 향상하기 위한 선택적인 방법 입니다.

Hash Cluster는 인덱스나 인덱스 Cluster를 가지는 Cluster되지 않은 테이블의 대용이며 인덱스 테이블, 인덱스 Cluster와 함께 오라클은 별도의 인덱스에 저장된 키값을 사용하는 테이블 내의 로우(row)에 위치 합니다.

또한 오라클은 물리적으로 Hash Cluster내의 테이블의 로우에 저장하고 Hash function의 결과에 의하여 검색 하는데 특정 Cluster 키값을 바탕으로 Hash Values라 불리는 분산된 수치 값을 생성하는 Hash Function을 사용 한다

댓글 없음:

댓글 쓰기