Oracle/튜닝

CBO, 테이블 통계, 인덱스 통계

pbj1102 2022. 1. 28. 09:48
반응형

CBO (Cost Based Optimizer) 비용 산정 을 위해 테이블 통계, 인덱스 통계, 히스토그램을 참조한다. 

 

 

 

 TUNING.ORDERS

ORDERNO ORDERDATE TOTAL PAYTYPE STATUS CUSTNO CODE
200004 2017-12-13 0:00 272900 신용카드 배송중 6091 29
200005 2017-12-15 0:00 61500 체크카드 배송중 5590 75
200006 2018-06-14 0:00 9700 체크카드 배송중 7693 7
200010 2019-11-24 0:00 593250 신용카드 결제완료 6162 62
200011 2019-06-30 0:00 575550 계좌이체 배송준비중 4498 98
200012 2018-02-22 0:00 9150 계좌이체 구매확정 3381 1
200013 2019-11-20 0:00 50700 신용카드 배송중 3822 25
200014 2017-11-30 0:00 62200 계좌이체 구매확정 1844 33
200015 2018-04-25 0:00 268400 신용카드 결제완료 1232 7
200007 2019-05-08 0:00 577350 체크카드 배송완료 4048 35
200008 2020-07-31 0:00 36200 체크카드 배송완료 6928 24
200009 2019-12-28 0:00 136250 계좌이체 결제완료 2152 96
200001 2019-03-17 0:00 92400 신용카드 배송완료 7568 93
200002 2020-03-22 0:00 329750 신용카드 배송완료 1684 84
200003 2018-02-07 0:00 693000 계좌이체 배송완료 9902 14
200034 2018-08-22 0:00 186300 체크카드 결제완료 7538 80
200035 2018-12-27 0:00 88900 계좌이체 구매확정 132 34
200036 2020-02-22 0:00 509000 체크카드 결제완료 2710 2
200037 2019-07-21 0:00 229000 신용카드 배송중 4656 12
200038 2020-02-06 0:00 164400 신용카드 배송준비중 7997 70

 

- TUNING.ORDERS 통계정보 수집

EXEC DBMS_STATS.GATHER_TABLE_STATS('TUNING', 'ORDERS');

 

SELECT NUM_ROWS, BLOCKS, LAST_ANALYZED FROM DBA_TABLES WHERE TABLE_NAME='ORDERS';

행의 갯수, 블럭 수, 통계 수집 날짜 등...

NUM_ROWS BLOCKS LAST_ANALYZED
899999 302559 2022-01-27 14:22

 

 

SELECT COLUMN_NAME, NUM_DISTINCT, LOW_VALUE, HIGH_VALUE, DENSITY, LAST_ANALYZED, HISTOGRAM
FROM DBA_TAB_COLUMNS
WHERE TABLE_NAME='ORDERS';

 

*

NUM_DISTINCT : 고유한 값의 갯수

DENSITY : 1/NUM_DISTINCT

HISTOGRAM : NONE < 수집 안됨

COLUMN_NAME NUM_DISTINCT LOW_VALUE HIGH_VALUE DENSITY LAST_ANALYZED HISTOGRAM
ORDERNO 899999 C102 C40215 0.0000011111 2022-01-27 14:27 NONE
ORDERDATE 1000 78750B0B010101 78780806010101 0.001 2022-01-27 14:27 NONE
TOTAL 15835 C133 C4021D06 0.0000631512 2022-01-27 14:27 NONE
PAYTYPE 3 EAB384ECA28CEC9DB4ECB2B4 ECB2B4ED81ACECB9B4EB939C 0.3333333333 2022-01-27 14:27 NONE
STATUS 5 EAB2B0ECA09CEC9984EBA38C EBB0B0EC86A1ECA491 0.2 2022-01-27 14:27 NONE
CUSTNO 10000 C102 C302 0.0001 2022-01-27 14:27 NONE
CODE 100 C102 C202 0.01 2022-01-27 14:27 NONE

옵티마이저는 문장을 실행하지 않고, 전체 행의 33.3%가 리턴되는 것으로 예측한다. 

SELECT * FROM TUNING.ORDERS WHERE PAYTYPE = '체크카드';

 

 

히스토그램의 개념

- 컬럼 값의 분포를 나타냄 

- 히스토그램 정보가 있으면, 옵티마이저는 쿼리를 실행하지 않아도, 몇 건의 결과가 리턴 될 것인지를 정확히 예측 할 수 있다. 

- 히스토그램 정보가 없으면, 옵티마이저는 해당 값이 최소값과 최대값 내에서 균등하게 분포되어 있다고 가정한다.

 => 즉, 특정 컬럼의 값 분포가 어느 한쪽으로 치우침 없이 균등하다면 히스토그램을 생성 할 필요는 없다.

 

 

히스토그램 수집 

EXEC DBMS_STATS.GATHER_TABLE_STATS('TUNING', 'ORDERS', method_opt=>'for all columns');

                                                                       -- 모든 컬럼의 히스토그램을 수집하겠다. 

 

SELECT COLUMN_NAME, NUM_DISTINCT, LOW_VALUE, HIGH_VALUE, DENSITY, LAST_ANALYZED, HISTOGRAM
FROM DBA_TAB_COLUMNS
WHERE TABLE_NAME='ORDERS';

 

* 히스토그램 수집 확인

COLUMN_NAME NUM_DISTINCT LOW_VALUE HIGH_VALUE DENSITY LAST_ANALYZED HISTOGRAM
ORDERNO 899999 C102 C40215 0.000001 2022/01/28 9:21:38 HYBRID
ORDERDATE 1000 78750B0B010101 78780806010101 0.000996 2022/01/28 9:21:38 HYBRID
TOTAL 15835 C133 C4021D06 0.000063 2022/01/28 9:21:38 HYBRID
PAYTYPE 3 EAB384ECA28CEC9DB4ECB2B4 ECB2B4ED81ACECB9B4EB939C 0.0000005555561728 2022/01/28 9:21:38 FREQUENCY
STATUS 5 EAB2B0ECA09CEC9984EBA38C EBB0B0EC86A1ECA491 0.0000005555561728 2022/01/28 9:21:38 FREQUENCY
CUSTNO 10000 C102 C302 0.0001 2022/01/28 9:21:38 HYBRID
CODE 100 C102 C202 0.009901 2022/01/28 9:21:38 HYBRID

* 히스토그램 생성 시(비용 계산 시) 

  히스토그램이 있으면 히스토그램 정보를 이용해서 조건에 의한 결과 값을 리턴

  히스토그램이 없다면 Density 로 컬럼에 의한 비율로만 계산함


SELECT endpoint_number, endpoint_value
FROM dba_histograms
WHERE table_name='ORDERS' AND column_name='PAYTYPE';

 

 

* 테이블 통계 수집 시, 많이 사용하는 옵션

EXECUTE DBMS_STATS.GATHER_TABLE_STATS('TUNING', 'ORDERS', method_opt=>'for all columns size skewonly', cascade=>true, no_invalidate=>false);

 

[method_opt=>'for all columns size skewonly'] : 컬럼 중에 분포가 불균등한 컬럼에 대하여 히스토그램 작성

[cascade=>true] : ORDERS 테이블과 연관된 객체에 대해서도 통계 수집

[no_invalidate=>false] : 캐시된 실행 계획 모두 무효화

 

 

 

 

인덱스 통계

: 인덱스는 생성 즉시 통계가 수집 된다.

CREATE INDEX TUNING.ORDERS_CODE_IDX ON TUNING.ORDERS (CODE) ;

 

 

인덱스 통계 직접 수집

: 인덱스가 참조하는 테이블의 컬럼들에 DML이 많이 수행된 경우, 인덱스의 통계를 갱신 할 필요가 있다.

EXEC DBMS_STATS.GATHER_INDEX_STATS('TUNING', 'ORDERS_CODE_IDX');

 

보통의 경우 테이블 통계를 수집하면서 테이블과 관련된 모든 객체에 대해 통계를 수집하는게 일반적이다. 

 

EXECUTE DBMS_STATS.GATHER_TABLE_STATS('TUNING', 'ORDERS', method_opt=>'for all columns size skewonly', cascade=>true, no_invalidate=>false);

 

 

SELECT blevel, leaf_blocks, distinct_keys, avg_leaf_blocks_per_key, avg_data_blocks_per_key, clustering_factor, num_rows, last_analyzed
FROM dba_indexes
WHERE index_name = 'ORDERS_CODE_IDX';

 

BLEVEL LEAF_BLOCKS DISTINCT_KEYS AVG_LEAF_BLOCKS_PER_KEY AVG_DATA_BLOCKS_PER_KEY CLUSTERING_FACTOR NUM_ROWS LAST_ANALYZED
2 2880 100 28 8826 882657 891134 2022/01/28
9:41:53

*

BLEVER : 브랜치 레이어의 수

LEAF_BLOCKS : 리프 블록 수

CLUSTERING_FACTOR : 클러스터링 팩터

 

* 테이블 내에 데이터가 아무리 많아도 브랜치 레벨의 수는 보통 3 이하이다.

  그러므로 4이상이 되면 통계를 다시 수집할 필요성이 있다.

클러스터링 팩터(Clustering Factor)?
: 리프 블록 내의 인덱스 항목들을 순차적으로 읽고, 테이블에 접근 할 때, 테이블 블록에 방문한 횟수
: 인덱스에 저장된 인덱스 항목의 정렬 순서와 테이블에 저장된 행의 정렬 순서가 얼마나 일치하는지를 나타내는 값

* 옵티마이저는 사용 가능한 인덱스가 여러 개 존재하면 브랜치 레벨과 클러스터링 팩터가 낮으며, 
  통계 자료가 최근에 업데이트 된 인덱스를 선호한다.

 

 

 

반응형

'Oracle > 튜닝' 카테고리의 다른 글

B-Tree 인덱스 구조  (0) 2022.02.10
FULL TABLE SCAN  (0) 2022.02.10
실행계획 순서분석  (0) 2022.01.28
DISPLAY_CURSOR  (0) 2022.01.28
SQL Tuning  (0) 2022.01.27