문서유형ㅣ기술정보
분야ㅣ관리/환경설정
적용제품버전ㅣ7FS02PS
문서번호ㅣTADTI176
개요
본 장에서는 히스토그램 대해 설명합니다.
방법
1. 히스토그램
쿼리 옵티마이저는 데이터가 균등하게 분포되어 있다는 원칙에서 시작합니다. 데이터가 균등하다면, Where 절에서 해당 컬럼을 기반으로 한 조건절이 필터링하는 로우의 수를 정확하게 추정하기 위해서 쿼리 옵티마이저는 컬럼정보에 있는 최솟값, 최댓값, distinct count 오브젝트 통계만 알면 됩니다.
하지만 데이터의 분포가 균일하지 않을 경우 추가적인 정보를 제공하지 않는다면 쿼리 옵티마이저는 수용할 수 있는 추정값을 정확하게 계산할 수 없습니다. 이렇게 데이터 분포도가 균일하지 않을 경우 쿼리 옵티마이저가 필요로 하는 추가 정보를 히스토그램(histogram) 이라고 합니다. 도수분포(frequency) 히스토그램과 높이균형(height-balanced histogram) 히스토그램이라는 두 가지 유형의 히스토그램을 사용합니다.
히스토그램이 수집 가능한 데이터 타입은 다음과 같습니다.
- NUMBER
- CHAR
- VARCHAR
- DATE
- TIME
- TIMESTAMP
히스토그램은 구간별 분포도를 표현하는 막대기의 집합으로 Tibero에서는 최댓값, 최솟값, Distinct count(고유값 개수) 등의 정보를 Bucket이라는 단위로 구간별 데이터 분포도의 정보를 저장합니다.
특정값의 분포도와 값의 범위는 이후 해당 Column의 조건문의 Selectivity와 Cardinality예측에 중요한 요소로 작 용합니다. 히스토그램을 어떻게 수집하느냐에 따라 Selectivity 및 Cardinality예측값을 변화시킬 수 있습니다. Cardinality는 Cost계산에 있어서 중요한 요소 중 하나이므로 Column통계 정보도 전략적으로 수집할 필요가 있습니다.
- 도수 분포(Frequency) 히스토그램
- 값별로 빈도수(frequency number)를 저장하는 Historgam입니다.
- 최대 256개의 Bucket만 허용하며, Distinct count 수가 256개를 넘는 Column은 사용할 수 없습니다.
- Column값마다 단일 Bucket을 할당하므로 Distinct count가 40개인 Column에 50개의 Bucket을 요청해도 40개의 Bucket이 생성됩니다.
- Distinct count가 적은 경우입니다. (Bucket 개수보다 적거나 같은 경우) 1개의 Bucket이 하나의 값을 가지게 되어 빈도를 정확하게 저장하고 있기 때문에 조건절을 만족하는 Cardinality를 쉽고 정확하게 계산합니다.
- END_POINT는 Bucket에 할당된 값을 NUMBER로 표현한 형태이며, END_POINT_ACTUAL은 보기 쉽게 문자 열로 표현한 값입니다.
- BUCKET은 END_POINT_ACTUAL로 정렬했을 때 최솟값부터 현재값까지의 누적 수량입니다.
- 높이 균형(Height-Balanced) 히스토그램
- Column이 가진 값의 수보다 적은 Bucket을 요청할 때 생성됩니다. (Distinct count가 METHOD_OPT에 지정한 Bucket 수보다 많은 경우)
- 256개 이상의 Distinct count가 있으면 Height-Balanced 히스토그램으로 생성됩니다.
- METHOD_OPT에 지정한 Bucket수만큼 생성됩니다.
- END_POINT는 Bucket이 담당하는 가장 큰 값을 NUMBER 형태로 표현한 값이며, END_POINT_ACTUAL은 문자열로 표현한 값입니다.
- BUCKET은 Bucket 번호입니다.
method_opt의 Bucket 개수와 Distinct count 두 값에 따라 어느 형태로 저장할지 결정되며, 일반적으로 Bucket 개수 보다 Distinct count가 많은 경우는 Height-Balanced 히스토그램을 사용합니다.
각 Bucket은 범위와 Distinct count의 정보를 통해 구간별 값의 분포도를 표현합니다. 만약 성별, 학년처럼 Distinct count가 적은 경우(Bucket 개수보다 적거나 같은 경우)는 더 정밀한 표현을 위해 Frequency 히스토그램을 사용하며, 고유값별 값이 몇 개인지의 정보를 저장합니다.
Frequency 히스토그램를 조회하면 다음과 같은 내용을 확인할 수 있습니다. (SYS._DD_HISTOGRAM)
| HIST_HEAD_ID | BUCKET (건수) | END_POINT (실제 값) | DISTINCT_CNT |
|---|---|---|---|
| 123 | 20 | 111 | 1 |
| 123 | 3 | 222 | 1 |
| 123 | 100 | 333 | 1 |
Table 해당 Column에는(샘플링된 데이터 기준) 111, 222, 333 세 종류의 값이 있고, 샘플링된 20+3+100=123 개의 값들 중 111은 20개, 222는 3개, 333은 100개가 존재합니다.
Column 이름이 C라고 할 때 C=111이라는 조건문이 있으면 선택도는 20/123이 되어 Table 통계 정보에 저장된 Row 개수와 곱해져서 Cardinality 예측이 나옵니다.
Height-Balanced의 경우 Bucket 내에 여러 고유값이 존재할 수 있고, Bucket 하나 안에서는 고유값들이 어떤 분포를 갖는지 알 수 없습니다. 따라서 "=” 조건에 대해서만큼은 Frequency 히스토그램이 더 정확합니다.
-- SYS._DD_HISTOGRAM 조회 쿼리 생성
SQL> SELECT HIST_HEAD_ID,BUCKET,END_POINT,DISTINCT_CNT
FROM SYS._DD_HISTOGRAM
WHERE HIST_HEAD_ID=(SELECT HIST_HEAD_ID
FROM SYS._DD_HIST_HEAD
WHERE (OBJ_ID,COL_NO)=(SELECT C.OBJ_ID,C.COL_NO
FROM SYS._DD_COL C, SYS._DD_OBJ O,
SYS._DD_USER U
WHERE O.OBJ_ID=C.OBJ_ID
AND O.OWNER_ID=U.USER_ID
AND U.NAME='TEST_USER'
AND O.NAME='TEST_TABLE'
AND C.NAME='TEST_COLUMN'))
/Table 통계 정보를 수집하는 쿼리는 기본적으로 Column별 최댓값, 최솟값, Distinct count 등을 계산하는 Aggregation 함수도 포함되어 있어 Bucket 개수가 1일 때 Table 레벨 통계 수집 쿼리 수행만으로 정보가 채워집니다. 하지만 Bucket 개수가 2 이상이 되면 Bucket별로 최댓값, Distinct count 등을 구하기 위해 Column 별로 별도의 통계 수집 쿼리가 수행됩니다.
Column의 데이터 분포도를 확인하기 위해 히스토그램을 사용하기 때문에 Column들의 값이 고르게 분포되지 않고 한쪽으로 치우친 경우 Column에 대한 히스토그램을 생성해야 합니다.
히스토그램의 특성상 Bucket 개수가 많을수록 더 정밀한 분포도를 표현하는 것은 사실이지만 대용량 환경에서 수 많은 개수의 Column들에 대해 히스토그램 수집을 수행하게 된다면, 상당한 수행 시간이 소요될 것이다. 따라서 데이터의 분포가 불균형한 Column에만 사용할 것을 권장합니다.
Plan 분석을 통한 히스토그램 대상을 선별하는 방법에 대한 자세한 내용은 “ 히스토그램 대상 선별 방법”을 참고합니다.