2009/01/08 13:21
※ 이 글은 "실전 SQL 튜닝" 강의를 듣고 개인적인 의견과 함께 정리한 내용입니다.

Cost Based Optimizer의 작동 원리


CBO의 작동 순서

사용자 삽입 이미지

CBO는 다음과 같은 순서를 거쳐서 수행 됩니다.

  1. Parsing 단계
    파싱 단계는 SQL 구문(syntax)과 의미검사(semantics)를 수행합니다. 예를 들어 SQL 구문이 정확한지 검사하고 참조된 테이블에 대해 사용자의 접근권한을 검사합니다. SQL은 파싱트리(parsing tree) 형태로 변형되어 옵티마이저에게 넘겨집니다.

  2. 옵티마이저(Qeury Optimizer)
    위 그림에서 점선형태의 사각형으로 표시된 부분이 옵티마이저의 주요 구성요소입니다. 각 구성요소의 역할은 아래와 같습니다.

  3. 질의 변환(Query Rewriter 또는 Transformer)
    질의 변환 단계는 파싱트리를 받아들여서 질의 변환을 수행합니다. 질의 변환은 사용자가 작성한 SQL문을 더 나은 실행계획을 찾을 수 있는 SQL문으로 변환합니다.

  4. 실행계획 생성(Plan Generator)와 Estimator
    오라클 옵티마이저는 실행계획 생성과 비용산정 모듈을 수행하기 전에 질의에서 사용된 모든 테이블들과 각 테이블에서 정의된 인덱스들에 관해 기본적인 통계정보들(테이블 블럭수, 로우의 평균길이, 인덱스의 높이, 인덱스 리프 블록의 수 등)과 각 테이블에 대한 다양한 엑세스 경로(Full table scan, Index scan 등)에 대한 비용정보를 미리 산출하여 Cost Model을 만듭니다. 이러한 일련의 정보를 바탕으로 옵티마이저는 최적의 실행계획을 생성하여 'Best Query Plan'을 작성합니다.

CBO에서만 가능한 기능들

CBO는 위와 같이 작동하기 때문에 RBO(Rule Based Optimizer)에는 없는 CBO에서만 가능한 기능들이 있습니다
  • 테이블 및 인덱스의 Partitioning
  • 인덱스 구성 테이블(Index-organized table)
  • Reverse Key Index
  • Function Based Index
  • SELECT 문장에서의 SAMPLE절
  • 병렬 Query 및 병렬 DML
  • Star Join 및 Star 변형
  • Optimizer 확장
  • Materialaized View를 이용한 Query rewrite
  • Enterprise Manager progress meter
  • 해쉬 Join
  • Bitmap 인덱스 및 Bitmap Join 인덱스
  • 인덱스 skip scan 알고리즘

CBO의  작동원리

  • 실행계획 중 cost가 가장 적은 실행계획을 선택
  • 컬럼별 데이터 분포에 대한 통계정보(=히스토그램) 사용
  • 복잡한 관계표현에서 때로 잘못된 실행계획을 수립할 수도 있는데 이런 경우 힌트를 사용하여 수정하도록 함
  • 오브젝트에 대한 통계정보를 기준으로 실행계획을 작성하므로 통계정보가 제대로 생성되어 있지 않은경우, 응용프로그램의 성능에 악영향을 미치게 되므로 주의
  • Cost engine은 I/O cost, Network cost, CPU cost 등도 고려하도록 설계되어 있음
※ 통계정보 : 테이블의 데이터 건수, 평균 실이, 컬럼 별 distinct 값의 수, 인덱스 leaf node의 depth 등이 저장
크리에이티브 커먼즈 라이선스
Creative Commons License
2008/11/24 08:43
※ 이 글은 "실전 SQL 튜닝" 강의를 듣고 개인적인 의견과 함께 정리한 내용입니다.

Cost_based Optimizer는 통계정보를 바탕으로 실행계획을 수립한다. 이는 Rule_based Optimizer보다 진보된 방법이지만 옵티마이저가 통계정보를 바탕으로 실행계획을 수립하기 때문에 sql이 작성자 의도대로 실행되지 않는 경우가 있기 때문에 실행계획 예측이 어렵다. 하지만 이런점은 초보자가 작성한 sql이라도 어느정도 성능을 보장해 주는 역할을 하기도 한다.
 실제 경험상 Oracle 9i에서 10g로 업그레이드만 했을 뿐인데도 쿼리의 실행 속도가 현저하게 빨라진 경우를 본적이 있다. 둘다 Cost_based Optimizer이긴 하지만 10g의 옵티마이저가 좀더 똑똑하다는(다양한 통계정보를 이용해서 실행계획을 잘 짜는) 이야기다. 이렇게 옵티마이저가 발전할 수록 옵티마이저는 최소한의 성능을 보장해 주고 좀더 빠른 실행속도를 보장해 줄 것이다.

 Cost_based Optimizer가 이용하는 통계정보
  1. 테이블의 로우 수와 블럭 수
  2. 블록당 평균 로우 수
  3. 로우의 평균길이
  4. 컬럼별 상수값의 종류
  5. 분포도
  6. 컬럼내의 NULL값의 수
  7. 클러스터링 팩터
  8. 인덱스의 깊이(Depth, Level)
  9. 컬럼의 최대, 최소값
  10. 리프(Leaf) 블록수
  11. 가동 시스템의 I/O, CPU정보
크리에이티브 커먼즈 라이선스
Creative Commons License
2008/11/24 08:23
※ 이 글은 "실전 SQL 튜닝" 강의를 듣고 개인적인 의견과 함께 정리한 내용입니다.

Optimizer에는 Rule_based와 Cost_based가 있다. Rule_based Optimizer는 아래와 RULE대로 우선순위를 적용해서 실행계획을 세운다. 또한 Cost_based Optimizer 또한 통계정보+RULE을 중심으로 실행계획을 세우므로 아래 순서를 외우지는 못하더라도 각 항목의 우선순위정도는 알아두면 좋을 것 같다.
  1. ROWID로 1로우 엑세스
  2. 클러스터 조인에 의한 1로우 엑세스
  3. Unique HASH Cluster에 의한 1로우 엑세스
  4. Unique INDEX에 의한 1로우 엑세스
  5. CLUSTER 조인
  6. Non Unique HASH Cluster Key
  7. Non Unique Cluster Key
  8. Non Unique 결합 인덱스
  9. Non Unique한 결합 인덱스
  10. 인덱스에 의한 범위처리
  11. 인덱스에 의한 전체 범위처리
  12. Sort Merge 조인
  13. 인덱스 컬럼의 MIN,MAX 처리
  14. 인덱스 컬럼의 ORDER BY
  15. 전체 테이블 스캔
크리에이티브 커먼즈 라이선스
Creative Commons License