메뉴 건너뛰기

bysql.net

7. 비용

2011.05.03 08:00

휘휘 조회 수:6167

  • I/O 비용모델
    • 예상되는 I/O 요청 횟수만을 퀴리 수행 비용으로 간주
  • CPU비용모델
    • I/O비용모델 + 시간개념


_optimizer_cost_model 파라미터


  • IO
    • I/O 비용모델
  • CPU
    • CPU 비용모델
  • CHOOSE
    • 시스템 통계가 있으면 CPU, 없으면 I/O비용모델


9i - 관리자가 시스템 통계를 생성해줄때 cpu비용모델로 작동

10g - NoWorkload 시스템통계의 추가


  • 쿼리 레벨로 비용모델 선택 힌트
    • cpu_costing
    • no_cpu_costing


(1) I/O 비용 모델

  • 비용
    • 디스크 I/O Call 횟수
  • 인덱스를 경유한 테이블 액세스 비용
    • single block I/O 방식 사용
    • 디스크에서 한블록을 읽을때마다 한번의 I/O Call을 일으킴
    • 물리적 블록 개수가 액세스비용(=I/O Call 횟수) 과 일치





SQL> create table t as select * from all_objects;

Table created.

SQL> create index t_owner_idx on t (owner);

Index created.

SQL> begin
 2  dbms_stats.gather_table_stats(user,'T'
 3  ,method_opt=>'for all columns size 1');
 4  end;
 5  /

PL/SQL procedure successfully completed.

SQL> alter session set "_optimizer_cost_model" = io;

Session altered.

SQL> set autot traceonly exp;
SQL> select /*+ index(t) */ * from t where owner='SYS';

Execution Plan
----------------------------------------------------------
Plan hash value: 910642575

---------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost  |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |  2904 |   263K|    84 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T           |  2904 |   263K|    84 |
|*  2 |   INDEX RANGE SCAN          | T_OWNER_IDX |  2904 |       |     7 |
---------------------------------------------------------------------------

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

  2 - access("OWNER"='SYS')

Note
-----
  - cpu costing is off (consider enabling it)

SQL>


인덱스 스캔단계 7
테이블 액세스 77 ( 84 - 7)
번의 Single Block I/O Call 이 발생할것으로 예상




인덱스를 이용한 테이블 액세스 비용



비용 = blevel +                                 -- 인덱스 수직적탐색 비용
        (리프 블록 수 * 유효 인덱스 선택도 ) +  -- 인덱스 수평적 탐색 비용
    (클러스터링 팩터 * 유효 테이블 선택도 )     -- 테이블 Random 액세스 비용



  • blevel
    • 브랜치 레벨, 리프블록에 도달하기까지의 브랜치 블륵수
  • 유효인덱스 선택도
    • 전체인덱스 조건절에 만족할것으로 예상되는 비율(%), 방문할 리프 블록 비율
    • 인덱스 Access Predicate에 의해 결정
  • 유효 테이블 선택도
    • 전체 레코드 중 인덱스스캔후 최종적으로 테이블을 방문할것으로 예상되는 비율 (%)
    • 클러스터링 팩터와 곱하여 예상되는 테이블 블록 개수를 구할수 있음
    • 인덱스 Access Predicate와 Filter Predicate에 의해 결정
  • 최종 테이블 선택도
    • 테이블 Filter Predicate까지 포함한 모든 조건절에 의해 결정


  • 인덱스 Access Predicate 와 인덱스 Filter Predicate 가 다른경우
    • 좌변 컬럼을 가공한 조건절
    • 왼쪽 ‘%’ 또는 양쪽 ‘%’ 기호를 사용한 like 조건절
    • 동일 컬럼에 조건절이 두개일때, 인덱스 엑세스로 사용되지 못한 조건절
  • 선택도는 SQL이 위 조건절을 포함하는 경우를 제외하고 유효인텍스 선택도와 유효 테이블 선택도는 항상 같음
  • 선택도는 num_distinct 컬럼 통계를 이용해 구하고
  • 브랜치 레벨, 리프블록수, 클러스터링 팩터는 인덱스 통계를 통해서 얻을수 잇음





SQL> select i.blevel, i.leaf_blocks, c.num_distinct, i.clustering_factor
 2     ,1+(i.leaf_blocks * 1/c.num_distinct) "인덱스 스캔 비용"
       ,1+(i.leaf_blocks * 1/c.num_distinct)
       + (i.clustering_factor * 1/c.num_distinct) "총 테이블 액세스 비용"
from    user_indexes i, user_tab_col_statistics c
where i.index_name='T_OWNER_IDX'
and     c.table_name=i.table_name
and     c.column_name='OWNER';
 3    4    5    6    7    8

    BLEVEL LEAF_BLOCKS NUM_DISTINCT CLUSTERING_FACTOR 인덱스 스캔 비용 총 테이블 액세스 비용
---------- ----------- ------------ ----------------- ----------------------- ------------------------------
        1         115           17              1303              7.76470588                     84.4117647

SQL>







Full Scan에 의한 테이블 액세스 비용


  • Multiblock I/O 방식 사용
  • db_file_multiblock_read_count 파라미터에 영향을 받음





SQL> select blocks from user_tables where table_name='T';

    BLOCKS
----------
      678

SQL>


 1* select /*+ full(t) */ * from t where owner='SYS'
SQL> /

22909 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873

----------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost  |
----------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  2904 |   263K|   258 |
|*  1 |  TABLE ACCESS FULL| T    |  2904 |   263K|   258 |
----------------------------------------------------------





db_file_multiblock_read_count 값에 따른 cost 변화


db_file_multiblock_read_countRowsBytesCost
22904 263K258
42904 263K164
82904263K105
162904263K67
322904263K43
642904263K28
1282904263K18





I/O 비용 모델의 비현실적인 가정


  • Single Block I/O와 Multiblock I/O는 비용이 같다
  • 캐싱 효과를 전혀 고려하지 않는다

를 보정하기 위한 파라미터 제공 (8 부터)


optimizer_index_cost_adj

  • 인덱스 탐색 비용을 조정
  • 값의 범위
    • 1~10,000
    • 100
      • 기본값
      • 한번의 i/o call을 통해 single block read방식으로 한븕 읽는 비용과
      • Multiblock Read 방식으로 여러블록을 읽는 비용을 같게 평가
    • 25
      • Single Block Read 방식의 I/O Call 비용을
      • Multiblock Read 방식의 I/O call 비용의 25%로 간주
  • 인덱스를 경유할때의 물리적 I/O비용 ( Single Block Read)을
  • Full Table Scan 할때의 물리적 I/O비용(Multiblock Read) 과 대비, 상대적 비용을 표현
  • 이 값이 낮을수록 옵티마이저는 테이블 스캔보다 인덱스 액세스를 선호



optimizer_index_caching


  • NL 조인시 inner 쪽 인덱스 블록을 매번 디스크에서 읽는다고 가정 ( optimizer_index_caching=0)
  • NL 조인에서 inner 쪽 인덱스 블록이 캐싱돼 있을 가능성을 옵티마이저에게 알려주는 파라미터
  • IN-List Iterator 방식으로 인덱스를 탐색할때 읽는 인덱스 블록 액세스 비용에도 영향을 미침
  • 값의 범위
    • 1~100
  • 높게 설정할수록 인덱스를 이용한 NL조인을 선호





(2) CPU 비용 모델


  • 블록 I/O 소량, 쿼리 수행 시간이 상당히 오래 걸리는 경우
    • 해시 조인할때, 해시 체인에 달린 레코드가 많이 해시 체인을 스캔하는 부하가 심할때
    • 캐싱된 블록을 반복적으로 읽을대, 한블록에서 매법 비효율적으로 많은 레코드를 스캔할때
      (NL 조인 Inner쪽 인덱스 선두 컬럼이 between 조건일때)
    • 버퍼를 Pin한 상태에서 같은 블록을 반복 액세스 할때
    • 다량의 레코드를 읽으면서 건건이 여러개의 사용자 정의 함수를 반복 호출할때
    • 메모리 소트를 반복할때


  • CPU 사용량이 증가 할때
    • 조건절 개수가 아주 많을때
    • 조건절이나 select-list 에 연산 집약적인 작업을 많이 포함할때


  • CPU 비용 모델에서의 비용 계산식




Cost=( #SRds * sreadtim +
    #MRds * mreadtim +
    #CPUCycles / cpuspeed

) /sreadtim



  • #SRds
    • Single Block I/O 요청 횟수
  • #MRds
    • Multiblock I/O 요청횟수
  • #CPUCycles
    • 쿼리 수행에 필요한 CPU 사이클 수
  • sreadtim
    • Single Block I/O에 소요되는 시간 (ms), 통계수집시 측정
  • mreadtim
    • Multiblock I/O에 소요되는 시간 (ms), 통계수집시 측정
  • cpuspeed
    • 초당 처리할 수 있는  CPU 사이클 수, 통계수집시 측정
    • CPU 속도를 초당 사이클 수로 표현한것
    • 사용자의 플랫폼에서 오라클이 수행해 본 몇 가지 표준 오퍼레이션의 초당 수행 횟수를 표현한것


I/O 비용


  • #SRds(Single Block I/O 요청 횟수)와 #MRds(Multiblock I/O 요청횟수)에
  • 미리 측정해 놓은 평균 소요시간 (sreadtim, mreadtim)을 각각 곱함으로써 I/O 일략을 시간으로 표현


cpu비용


  • I/O 비용과 함께 CPU비용을 계산식에 포함
  • '예상 cpu 사이클수 #CPUCucles' 를 초당 처리할수있는 CPU사이클수 (cpuspeed)로 나눈 값으로 계산
  • 예상CPU사이클 수
    • 순수한 CPU 연산 비용과 버퍼 캐시에서 데이터를 읽는 CPU 비용까지 포함
  • I/O 시간과 cpu연산 시간을 더한값을 Single clock I/O 평균소요시간 (sreadtim)으로 나눔
    -> single block i/o에 소요되는 시간과의 상대적인 시간 비용으로 표현

  • 쿼리의 예상 총 수행 시간을 single block i/o 시간 단위로 표현한것





  • 오라클 고도화 원리와 해법 2 (bysql.net 2011년 1차 스터디)
  • 작성자: 남송휘 (tofriend)
  • 최초작성일: 2011년 5월 1일
  • 본문서는 bysql.net 스터디 결과입니다 .본 문서를 인용하실때는 출처를 밝혀주세요. http://www.bysql.net
  • 문서의 잘못된 점이나 질문사항은 본문서에 댓글로 남겨주세요. ^^


번호 제목 글쓴이 날짜 조회 수
40 10. 실체화 뷰 쿼리로 재작성 suspace 2011.06.07 5531
39 9. Outer 조인을 Inner 조인으로 변환 darkbeom 2011.06.07 7834
38 8. 공통 표현식 제거 darkbeom 2011.06.07 5223
37 12. 기타 쿼리 변환 [3] 실천하자 2011.06.03 6646
36 4. 조건절 Pushing 실천하자 2011.05.31 7021
35 7. OR-Expansion 멋진넘 2011.05.31 8720
34 6. 조인 제거 멋진넘 2011.05.30 4595
33 5. 조건절 이행 휘휘 2011.05.30 5406
32 2. 서브쿼리 Unnesting darkbeom 2011.05.16 19700
31 3. 뷰 Merging 실천하자 2011.05.15 23381
» 7. 비용 휘휘 2011.05.03 6167
29 1. 쿼리 변환이란? 실천하자 2011.05.02 4927
28 8. 통계정보 Ⅱ [1] 멋진넘 2011.04.30 31079
27 5. 카디널리티 suspace 2011.04.26 5953
26 4. 통계정보 Ⅰ darkbeom 2011.04.26 18091
25 6. 히스토그램 실천하자 2011.04.25 10917
24 3. 옵티마이저의 한계 멋진넘 2011.04.19 7857
23 1. 옵티마이저 file 실천하자 2011.04.18 11211
22 2. 옵티마이저 행동에 영향을 미치는 요소 휘휘 2011.04.18 5094
21 8. 고급 조인 테크닉-2 file suspace 2011.04.05 7017