2015년 5월 11일 월요일

SQL 실행계획 (힌트 종류)


위 책을 읽으면서 머리속에 정리한 글
(이론 서적의 경우엔 제 개인적 주관이 다분이 포함해서 작성합니다.)

1. 서두
    엑세스 효율에 가장 결정적인 영향을 미치는것은 
     수립된 실행계획이다

  실행계획은 다음 내용에 대해 영향을 받는다.
     ① SQL 형태(쿼리문 형태)
    ② 테이블 및 인덱스 구조
    ③ DBMS버전 
    ④ 통계정보

   빠르게 자료를 찾기 위해서는 
    물리적인 연결고리 없이(아직 디스크 엑세스를 하기전) 논리적인(?) 
    방법으로 어떻게 검색하면 빠르게 될지 결정하는 게 필요하다 
    그 역할을 하는게 옵티마이저(Optimizer, 최적기)

⇒ 엑세스 효율에 있어서 가장 중요한건 Optimizer 이다.

2. 옵티마이저(Optimizer)
   1) 의미
      DB엔진 내부의 프로그램이며 혹은 DB엔진 코어 이기도 하다.
       쿼리문을 가지고 처리 절차를 생성하고, 
       실행 가능한 수행 모듈로 만들고, 실행 완료 후 결과 리턴 하는 역할

   2) 옵티마이저의 형태
      규칙기준 옵티마이저 (RBO, Rule Based Optimizer)
      비용기준 옵티마이저 (CBO, Cost Based Optimizer)

   3) 규칙기준 옵티마이저 
     (1) 의미 : 
         일정 기준에 의거하여 검색순서를 정하는 방법(거의 고정되어 있음)
     (2) 기준 : 
         인덱스 구조비교연산자 우선순위를 기준으로 최적의 경로를 선택함
     (3) 장점 : 
         - 조금만 연습하면 이 기준에 부합한 Query 작성이 가능하다.
            (사용자 예측이 가능)
         + 사용자에 의해 최적화된 쿼리 작성이 유도되고 가능해진다.
     (4) 단점 : 
         - 통계정보라고 하는 현실요소를 무시한다는점
         - 좀더 많은 방식으로 검색순서를 당겨줄수 있는데 제한되는 도구들

   4) 비용기준 옵티마이저
     (1) 의미
         - 처리방법들이 나열되어 있다면 이에 대한 쿼리의 비용을 산정해보고
             이중 가장 적은 비용이 드는 애를 선택하는 방법
         - 위의 처리를 위해서 다양한 통계정보를 참조함
     (2) 장점
         - 현실을 감안한 판단이 가능하다
         - 통계정보 관리를 통해 최적화를 간접적으로 제어 할 수 있다.
         - 옵티마이저 깊이 이해하지 않더라도 어느정도의 성능을 보장한다.
       ① 통계정보를 이용하기위해 분포도라는 개념을 이용하는데 방식은 아래와 같다.
         - 컬럼값의 범위가 일정하여 레코드가 5000개인 테이블의 
         - 한 컬럼의 1~50까지를 떼어내 
         - 로우숫자와 범위를 보관하는 방법
         (넓이 균형 히스토그램(Width Balanced Histogram))
         - 값이 들쑥날쑥해 애매한 경우에는 부분을 떼어내 각 부분별 
             범위최소,최대값을 저장하는 방법
         (높이균형 히스토그램(Height Balanced Histogram))
       ② DBMS가 제공하는 기능중 테이블 모니터링 하는 기능을 이용하는 방법
       ③ 통계정보를 주기적으로 갱신하는 방법 
           (하지만 너무 자주해야 할정도로 급격하게 시스템이
           영향을 받는다면 구조부터 뜯어고쳐야 할 상황이라고 보면됨)
     (3) 단점
         - 예측한 결과대로 실행계획이 나타난다는 보장을 할수 없음
         - DBMS 버전에 종속적이다. 
            (영향 많이 받으며 버전 업그레이드시 많은 요소를 고려해야 한다.)
         - 실행계획 제어가 어렵다(첫번째와 같이 이해하면 될듯)
     (4) 주의할점 : 
         - 옵티마이저에서 통계정보는 100% 빠른 조회를 보장하지 않는다.
         - 다만 높은 확률의 빠른 조회조건을 보장한다.
            (빠르다는거야 아니라는거야?)
         - 통계정보를 수집, 이용하기위해서 
             DBMS에서 제공하는 여러 정보들을 습득할 필요가 있음
     (5) 옵티마이저 모드 종류
         - 초기결과 최적화(First_rows)
             일단 한줄이라도 먼저 나오게 하겠다
         - 전체결과 최적화(All_rows)  
            결과적으로 모든 결과를 빠르게 나오게 하겠다.
            두가지 모드에 따른 조회 시간에 큰 영향을 주지는 않는다고 한다.
     (6) 실행계획을 옵티마이저에 의해서 매번 계산하면 주로 빠르게 되겠지만
         가끔 늦기도 하고 다른 계획으로 진행되기도 하고 매번 고르기도 한다.
         이를 줄여주기위해서 아우트라인(Outline) : 
             실행계획의 요약본을 저장했다가 해당 쿼리가 오면 또는 
               비슷한 쿼리가 오면 이를 참조하여 실행계획을 수립하는 기능이다.
               CREATE 명령으로 만들어지며 속성을 ALERT 로 변경하는등의 기능을
               DBMS 별로 지원한다.
     (6) 옵티마이저의 한계
            완벽하지 않은(과거의 )통계정보를 바탕으로 앞으로의 쿼리를 
              정확하게 빠르게 조회되도록 실행계획을 작성할수 있게 지원할수 있나? 
              (100%는 아님, 효율을 높일뿐)
            = 이 아닌 BETWEEN , IN LIKE 등으로 검색시에는 오차가 크게 발생할 수 있음
              값들이 지니는 분포도가 일정치 않은 경우 옵티마이저의 효율은 
              떨어질 수 밖에 없다
            적절한 인덱스, 클래스터링을 결정, 쿼리문 자체에서 
              신경을 쓰는게 가장 중요함
     (7) 옵티마이저의 최적화 절차
            보유하고 있는 스키마객체, 통계정보 를 기초로 하고
              힌트나 아우트라인 등을 참조하여
              논리적으로 적용 가능한 처리 경로를 대상으로 가장 효율적인걸 택한다.
       ① 옵티마이저 실행 순서 및 형태
            (옵티마이저 실행전임)SQL문을 파싱 수행(DB)
            (옵티마이저 영역) 
              데이터 딕셔너리 통계정보 기반으로(데이터 분포도, 테이블 저장 구조와 특성
              , 인덱스 구조, 파티션 형태, 비교연산자) 질의 변환 (질의 변환기)
            그리고 비용을 계산(비용산정기)  --> 이 비용이 예상 계수 라고 하더라
            그리고 가장 최소 비용(예상계수)을 가진 실행계획을 선택 (실행계획 생성기)

       ② 질의 변환기 
            적절한 형태로 SQL을 변환시켜 주는것 변환 기술로는
            뷰병합 (뷰 정의시 지정한 쿼리를 엑세스 쿼리에 병합시켜 넣음)
            조건절 진입 : 뷰쿼리 로 조건절을 진입시켜 좀더 빠른 반응을 얻어냄
            서브쿼리 비내포화 : 합칠수 있는건 합치고 조건을 변경하여 서브쿼리를
              메인쿼리의 일부로서 같이 진행함
            실체뷰 쿼리 재생성 : 사용자가 입력한 쿼리를 옵티마이저가 재생성함
            OR 조건의 전개 : 여러 쿼리로 분기 + UNION으로 연결하는 질의로 변경
            사용자 엉의 바인드 변수 엿보기 : 최초 수행될때 적용된 값을
              이용해 실행계획을 수립하고 이를 공유하는 방법
       ③ 비용산정기 
            옵티마이저는 선택도, 카디널러티, 비용을 측정한다.
            선택도(Selectivity)
              대상 집합(전체 또는 부분집합)에서 조건을 만족하는 로우가 차지하는 비율
            카디널리티(Cardinality)
              판정 대상이 가진 결과건수, 혹은 다음 단계로 가지고 들어가는 중간 결과건수
            비용(Cost)
              실행계획 상의 각 연산들을 수행시 소요되는 시간비용을 상대적으로 예상한 수치
       ④ 실행계획생성기
            적용 가능한 실행계획을 선별하고 비교검토 후 가장 최소의 비용을 가진것을 선택

     (8) 질의의 변환
       ① 기본 변환방법에는
            Like 는 '%' '-'를 안썼을시 = 연산으로 조건절을 단순화 함
            IN 은 OR + '=' 으로 분리
            ANY, SOME 은 EXISTS 연산자로 변환
            ALL 은 '=' 와 AND 논리 연산자로 변환
            NOT ANY 는 EXISTS 연산자를 이용한 서브쿼리로 변환
            BETWEEN 은 >= 와 <= 으로 쪼개는 변환 작업 진행
            NOT 은 좀 복잡함 반대 비교연산을 찾아서 대체함 (< , >, <=, >=)
            서브쿼리의 NOT 도 마찬가지임( = , <>)
            같은 컬럼으로 두개 이상의 조건식을 주면 8번까지 규칙에 추가되는
              계산식들이 추가되는데 이해가 어려웠다
            3단논법(A는B고B는C면 A는C다)
       ② 뷰병합(View Merging)
            뷰를 사용하는 쿼리는 뷰쿼리, 엑세스 쿼리로 나누어진다.
              뷰 쿼리란 : FROM  절안에 가로로 묶어진 안의 SELECT 절)
              엑세스 쿼리 : 일반 쿼리문
            뷰병향(View Merging)법 : 뷰쿼리를 엑세스쿼리에 병합해 넣는 방식
            조건절(Predicate pushing) 진입법 : 뷰병합법이 안될때 뷰쿼리 내부에
              엑세스 쿼리의 조건절을 넣어서 뷰쿼리를 빠르게 하는 방식
              조건절 진입법을 활성화 하려면 DB 셋팅값의 파라미터 2개를 설정해주면
              좀더 복잡한 상황에서도 조건절 진입을 시도하게 된다.
       ③ 사용자 정의 바인드 변수의 엿보기(Peeking)
            모든 파싱 끝 후의 최적화가 끝나는 시점까지 실제 SQL 구문의 변수는
              볼수 없는게 원칙이나
              첫번째 파싱때 이 값을 확인하고 최적화에 도움을 주는 방식 PEEKING
              이라고 한다.

3. 실행계획의 유형
    1)  종류
      스캔을 위한 실행계획
      데이터연결을 위한 실행계획
      각종 연산을 위한 실행계획
      기타 특수한 목적을 처리하는 실행계획

    2)  스캔의 유형
     (1) 전체 테이블 스캔
            테이블에 있는 모든 로우를 읽어내는 방법(제일 안좋아요)
            다만 DB 옵션중 엑세스 하는 블록 양을 정할 수 있다 대량 엑세스가 많다면 유효함
            전체 테이블 스캔을 할수 밖에 없는 경우란
              적용 가능 인덱스의 부재
              넓은 범위의 데이터 스캔
              소량의 테이블 엑세스
              병렬처리 엑세스
              FULL 힌트를 적용시
     (2) ROWID 스캔
            단 하나의 로우를 테이블에서 추출하는 가장 빠른 방법
            전체조건은 ROWID를 확보하고 있어야 한다는 점
     (3) 인덱스 스캔
            가장 많이 이용하는 방법 종류가 좀 있다.
            인덱스 유일 스캔
              단 하나의 ROWID를 추출하는 방법, 
              힌트 적용시 자주 씀, 
              특정 인덱스 사용하는 DB 옵션을 주면 됨 
            인덱스 범위 스캔
              인덱스 스캔중에서 가장 보편적인 엑세스 형태 LIKE 에 %는 제한됨
            인덱스 역순 범위 스캔
              이거나 범위 스캔이나 뭐...
            인덱스 스킵 스캔
              인덱스의 일부만 보고 나오는 방식으로 인덱스를 이용한 스캔방법
              적은수의 인덱스로도 최적의 전략을 뽑아낼수 있음
              인덱스를 보기위한 방법을 쓰므로 서브 인덱스 라고도 불리운다.
              몇가지 힌트를 적용해서 사용 가능하다
            인덱스 전체 스캔
              쿼리 내의 조건절 컬럼이 인덱스에 다 있고 이 컬럼중 NOT NULL인게 하나는
                있어야함
            인덱스 고속 전체 스캔
              전체 스캔과 같지만 애는 아예 테이블 자체를 안봄
              인덱스만 보고 결과를 줘버림
              몇가지 힌트를 줘서 실행가능함
     (4) B-Tree 클러스터 엑세스
            클러스터링 기법으로 물리적인 엑세스 공간을 제한해서 진행함 첫 게시물과 중복
     (5) 해쉬 클러스터 엑세스
            데이터 클러스터링 팩터를 높여 물리적인 I/O를 줄이고 효율을 향상시키기 위한 방법
            랜덤 엑세스에 강하며 약 30% 효과를 본다고 한다.
     (6) 표본 테이블 엑세스
            사용자가 부여한 비율만큼만 데이터를읽고 결과값을 줌
            이 쓸데없는걸 왜 쓰냐면 데이터 마이님, 데이터 정제 같은 작업을 위해 쓰거나
               테이스틑 위해 표본을 생성하려고 할때 적용함

    3)  데이터 연결을 위한 실행계획
       단일 테이블을 엑세스 하는 질의를 던져도 실제 내부에서는 join을 쓴다.(?)
     (1) 내포 조인 _ 먼저 수행되는 집합의 처리범위가 전체 일량을 좌우하는 형태
            ※ 진보된 내포 조인 물리적인 블록별로 조회할수 있는건 조회하고 넘어가는 방식
     (2) 정렬 병햡 조인 
     (3) 해쥐 조인
            해쉬 함수를 통해 조인 을 수행하는데 이때 해쉬 함수의 역할은
              연결될 대상을 특정 지역(파티션)에 모와두기만 함 옵션으로 통제
     (4) 세미조인
     (5) 카티젼 조인
            두 집합간 연결고리가 전형 없는 N:N 관계로 나오게되는 조인
     (6) 아우터 조인
            기준 집합의 모든 로우들을 리턴
     (7) 인덱스 조인
            테이블을 조회하지 않고 인덱스만 보고 결과를 주는 조인 방법

    4)  연산방식에 따른 실행계획
     (1) IN_List 탐침 실행계획
            in 연산자는 or 로 바뀌여서 실행된다.
     (2) 연쇄 실행계획
            or는 각각 실행되며 각각 최적의 경로를 찾아 실행하여 이를 연결한다.
     (3) 원격 실행계획
            다른 DATABASE 테이블을 데이터베이스 링크 라는 기술을 통해
              연결하여 엑세스 하는 방식 (연동시 필요한듯)
     (4) 정렬 처리
            정렬 하는 방식에 따라 DB가 느끼는 부하가 틀리게 된다.
            - SORT(UNIQUE)  : 
            - SORT(AGGREGATE) : 그룹함수 계산시 쓰임
            - SORT(GROUP BY) : 전체 GROUP를 짓기 때문에 데이터가 많으면 부담이 크다
            ⇒ 이 문제 개선을 위해 10G부터는HASH(GROUP BY) 라는 기술이 적용된다.
     (5) 집합처리 실행계획
            합집합, 차집합, 교집합
     (6) COUNT(STOPKEY) 실행계획
            ROWNUM 사용시 발생함

    5)  비트맵 실행계획
     (1) B-Tree 인덱스와 다르게 모든 연산자에 써먹을수 있다.
     (2) B-Tree 인덱스와 연합하여 사용이 가능하다 ROWID 를 비트로 바꿔
           비트맵 연산을 수행한다. 힌트 적용시 쓰게됨

    6)  기타 실행계획
     (1) 뭐뭐가 있나
            ① 순환 전개 실행계획 : CONNECT BY .... START WITH 구문 사용시
            ② UPDATE SET 절 서브쿼리 실행계획
               UPDATE 절의 SET, WHERE 에서 사용하는 서브 쿼리를 
                 스칼라(Scalar) 서브쿼리라고 한다.
            ③ 특이한 형태의 실행계획 (이건 여러개가 있음)
             - 서브쿼리 팩토링 실행계획  
                (with  절을 써서 임시 테이블에 물리적인 저장후 꺼내쓰는 방식
                   : 빨라지지만 이후 쿼리변형이 불가능해짐)
            - 특이한 DELETE 문 서브 쿼리
                (DELETE 안에 서브쿼리에 JOIN을 씀)
            - 다중 테이블 입력 서브 쿼리
                (하나의 쿼리에서 여러 테이블에 다른 쿼리를 실행하게끔 함)
            - HAVING 절 서브쿼리 실행계획 : HAVING 절 사용시 나타남
            - ROLLUP, CUBE, GROUPING SETS 처리 실행계획
                 (소계를 빠르게 해주는 실행계획)
            - MERGE 실행계획
                 (어떤 테이블에 데이터 처리시 CRUD 가 복합적으로 실행될때)
            ④ 종합 실행계획 사례 연구

4. 실행계획의 제어
    1)  실행계획과 힌트
      힌트는 하나의 훈수다 설정값을 했다고 해서 
         DBMS 가 무조건 따르지는 않는다.
      힌트 사용 위치는 각 CRUD 시작후 바로 작성해준다.
                ex) SELECT /*+ ALL+ROWS */ NAME, AGE, KEY FROM ASKY ...

 힌트 관련 참고 링크 여기 힌트 목록을 ASC 순으로 잘 해놨음 빠르게 참고할꺼면 여기를 보세요

    2)  최적화 목표를 위한 제어 힌트
     (1)  ALL_ROWS : 전체 결과를 뽑아내기 위한 최적화를 목표한다.
                ex) /*+ ALL_ROWS */
     (2) CHOOSE  : 통계정보 유무를 보고 규칙기준, 비용기준을 적용해
           최적화를 수행한다.
                ex) /*+ CHOOSE +/
     (3) FIRST_ROWS : 최적 응답시간을 목표로 최저 비용의 계획을 목표한다.
                ex) /*+ FIRST_ROWS (n) +/ ⇒ N개 결과를 먼저 빼는게 목표임
     (4) RULE : 규칙기준 을 우선시 한다.
                ex) /*+ RULE +/

    2) 조인 순서 조정을 위한 힌트
     (1) ORDERED  : 작성된 테이블 순서대로 조인 수행하도록 유도
                LEADING 힌트보다 ORDERED 힌트가 우선시 된다.
                ex)  /*+ ORDERED +/
     (2) LEADING : 테이블 순서와 상관없이 조인 순서를 제어함
                 ex) /*+ LEADING (table) +/

    3) 조인 방법 선택용 힌트
     (1) USE_NL : Nested Loops 방식으로 조인 수행유도, 조인 순서와는 별개임
           테이블을 많이 적으면 느려질듯
                ex) /*+ USE_NL (table [table]...) +/   
     (2) NO_USE_NL : USE_NL와 반대임
                ex)  /*+ NO_USE_NL +/
     (3) USE_NL_WITH_INDEX : USE_NL + INDEX 힌트를 같이 쓰는것과 같은 효과
                ex) 
     (4) USE_HASH : 해쉬조인 방식으로 조인 수행되도록 유도하는 힌트
                ex) /*+ USE_HASH (table [table]...) +/
     (5) USE_MERGE : Sort Merge 방식 조인 수행 , ORDERED 와 같이 사용권장
                ex) /*+ USE_MERGE (table [table]...) +/

    4) 병렬처리 관련 힌트
       병렬처리를 하여 빠르게 조회되겠지만 시스템이 좋다면 쓰고....
     (1) PARALLEL : 대량 테이블 DML 처리시 SQL 병렬처리 지시 힌트
                ex) /*+ PARALLEL (table [ [,n|, DEFAULT |,] [,n| DEFAULT ]]) +/
     (2) NOPARALLEL : 병렬처리를 하지 않는다. NO_PARALLEL 로도 쓰임
                ex)  /*+ NOPARALLEL (table) +/ 
OR /*+ NO_PARALLEL (table) +/ 
     (3) PQ_DISTRIBUTE : 병렬 조인 속도 향상을 위한 옵션
                ex) /*+ PQ_DISTRIBUTE () +/  ()부분에 옵션값 적어 줄 것
     (4) PARALLEL_INDEX : 파티션인덱스 에 대한 인덱스 범위 스캔을 병렬로실행
                ex) /*+ PARALLEL_INDEX (table [ [index] [, index]...]
[ [, n |, DEFAULT |, ] [, n | DEFAULT ] ] ) +/
           테이블을 지정해 주고, 그 밑에 몇개 돌릴것인지 지정
     (5) NOPARALLEL_INDEX : (4)의 반대
                ex) /*+ NOPARALLEL_INDEX (table [index] [index]) +/

    5) 엑세스 수단 선택을 위한 힌트
     (1) FULL : 힌트내 정의된 테이블을 전체 스캔 방식으로 유도함
                ex) /*+ FULL +/    뒤에 테이블명 넣기도 하고
     (2) HASH : Hash Cluster Table 엑세스시 해쉬 스캔 방식으로 엑세스 유도
                ex) /*+ HASH */   뒤에 테이블명 넣기도 하고
     (3) CLUSTER : Cluster Table 엑세스시 클러스터 인덱스를 통해 엑세스 유도
                ex)  /*+ CLUSTER  +/   여기도 테이블명 넣기도 하고
     (4) INDEX : 인덱스 범위 스캔에 의한 테이블 엑세스 유도 
                ex)  /*+ INDEX  TABLE명 [인덱스명] +/
     (5) NO_INDEX : 실행계획에 인덱스 스캔을 제외하고 진행
                ex) /*+ NO_INDEX  +/
     (6) INDEX_ASC : 인덱스 경우시 오름차순(정순)으로 유도
                ex) 인덱스와 같음 INDEX 대신 INDEX_ASC만 들어감
     (7) INDEX_DESC : (6) 반대
                ex) 인덱스와 같음 INDEX 대신 INDEX_DESC만 들어감
     (8) INDEX_COMBINE : 2개 이상 인덱스를 비트맵 인덱스로 변경, 결합해
          테이블을 엑세스 하는 방식으로 유도 (뭔가 좋아보임)
                ex) /*+ INDEX_COMBINE  .... ) +/
     (9) INDEX_FFS : 인덱스 전체 범위를 스캔하도록 유도
                ex) /*+ INDEX_FFS  .... +/
     (10) INDEX_JOIN : 2이상의 인덱스만으로 조인 수행하도록 유도
                ex) /*+ INDEX_JOIN ..... +/
     (11) INDEX_SS : 인덱스 엑세스시 인덱스 스킵 스캔 방식으로 스캔유도
                ex) /*+ INDEX_SS ..... +/
     (12) INDEX_SS_ASC : (11) 의 정방향부터 스캔 유도
                ex) /*+ INDEX_SS_ASC ..... +/
     (13) INDEX_SS_DESC : (11) 의 역방향부터 스캔 유도
                ex) /*+ INDEX_SS_DESC ..... +/

    6) 쿼리형태 변형을 위한 힌트
     (1) USE_CONCAT : OR, IN 을 떼어내서 구한후 붙이도록 유도
                ex) /*+ USE_CONCAT +/
     (2) NO_EXPAND : USE_CONCAT 반대
                ex) /*+ NO_EXPAND +/
     (3) REWRITE : 중간 결과물인 '뷰'를 물리적으로 생성하도록 유도
                ex)   /*+ REWRITE [ ( [뷰이름]...) ] +/
     (4) NOREWRITE : REWRITE 반대이며 REWRITE보다 우선적용된다.
                ex) /*+ NOREWRITE +/
     (5) MERGE : 뷰병향 유도 (쿼리를 변형함, 복잡한 쿼리에 효과를 볼 수 있음)
                ex) /*+ MERGE 테이블명 +/
     (6) NO_MERGE : (5)반대
                ex) /*+ NO_MERGE 테이블명 +/
     (7) STAR_TRANSFORMATION : 스타변형조인 을 수행하도록 요구하는 힌트
                ex) /*+ STAR_TRANSFORMATION +/
     (8) FACT : 스타변형조인 에서 팩트 테이블을 지정하기위해 사용
                ex) /*+ FACT 테이블명 +/
     (9) UNNEST : 서브, 메인 쿼리를 조인 형태로 바꿔 실행하도록 유도
                ex) /*+ UNNEST +/
     (10) NO_UNNEST : (9) 반대 
                ex)   /*+ NO_UNNEST +/

    7) 기타 힌트
     (1) APPEND : INSERT 문에 해당 빠른 입력을 보장(위치를 지정함)
                ex)  /*+ APPEND */
     (2) CACHE : 전체 테이블 스캔 결과물을 메모리에 놔두는 힌트
                ex) /*+ CACHE 테이블명 +/
     (3) NOCACHE : (2) 반대
                ex) /*+ NOCACHE 테이블명+/
     (4) CARDINALITY : 쿼리전체 혹은 일부 예상값을 실행계획 수립에 참고 유도
                ex) 
     (5) CURSOR_SHARING_EXACT : CURSOR_SHARING 초기화 파라미터를
               EXACT 로 지정함 ⇒ 있는 그대로 파싱함
                ex) /*+ CURSOR_SHARING_EXACT +/
     (6) DRIVING_SITE : 원격 테이블과 조인시 사이트를 지정해 최적화
                ex) /*+ DRIVING_SITE 테이블명 +/
     (7) DYNAMIC_SAMPLING : (통계정보를 아직 만들지 않았더라도 비용정보를
              우선하여 실행계획 작성토록 유도 하는 기능)을 쓰지 않고자 할때
                ex) /*+ DYNAMIC_SAMPLING ( [table] n ) +/ 
           N이 높을수록 상세하게 통계정보를 저장함
     (8) PUSH_PRED :뷰, 인라인뷰 외부 조인 조건을 뷰 쿼리 내요 삽입하는 힌트
                ex)  /*+ PUSH_PRED 테이블명 +/
     (9) NO_PUSH_PRED : (8)반대
                ex) /*+ NO_PUSH_PRED 테이블명 +/
     (10) PUSH_SUBQ : 머지되지 않은 서브쿼리를 최대한 먼저 수행토록 유도
             서브쿼리 수행속도가 전체 속도를 좌우할때 쓰인다
                ex)  /*+ PUSH_SUBQ +/
     (11) NO_PUSH_SUBQ : (10) 의 반대
                ex)  /*+ NO_PUSH_SUBQ +/
     (12) QB_NAME : 쿼리 블록에 이름을 부여하여 다른 힌트에서 참고할 수 
             있게 지정하는 힌트 (쿼리 블록 이름은 유일해야 함)
                ex) 
     (13) REWRITE_ON_ERROR : 적합한 실체 뷰가 없는 경우 에러를 발생시키고
             쿼리를 중단시켜버림 (ORA-30393)
                ex) 


~3장 끝

댓글 없음:

댓글 쓰기