오라클 성능 고도화 원리와 해법 II (2016년)
히스토그램 0 0 3,061

by 구루비 히스토그램 HISTOGRAMS [2017.05.09]


h1.히스토그램

  • 오라클은 히스토그램을 사용하여 데이터 분포가 고르지 않은 환경에서 Selectivity와 Cardinality 계산을 향상시킴
  • 데이터 분포가 고르지 않을 때 히스토그램을 생성하지 않으면 NDV( Number of Distinct Value) 값을 활용하여 Cardinality를 계산하지만 히스토그램을 생성하면 정확하게 Cardinality 값을 계산할 수 있다.

h3.(1) 히스토그램 유형

  • 높이균형 (Height-Balanced) 히스토그램
  • 도수분포(Frequency) 히스토그램
  • 히스토그램을 생성하려면 컬럼 통계수집시 버킷 개수를 2 이상으로 지정
  • dba_histograms 또는 dba_tab_histograms 뷰를 통해 확인
  • FREQUENCY : 값별로 빈도수를 저장하는 도수분포 히 스토그램(값의 수 = 버킷 개쉬
  • HEIGHT-BALANCED: 각 벼킷의 높이가 동일한 높이균형 히스토그램(값의 수 > 버킷 개쉬
  • NONE: 히스토그램을 생성하지 않은 경우

-- sample
create sequence seq;
create table member( mem_id number, age number( 2 ) );
exec dbms_random.seed(0);
insert into member
select seq.nextval, dbms_random.value( 1,19 ) from dual connect by level <= 50;
insert into member
select seq.nextval, dbms_random.value( 20,29 ) from dual connect by level <= 270;
insert into member
select seq.nextval, dbms_random.value( 30,39 ) from dual connect by level <= 330;
insert into member
select seq.nextval, dbms_random.value( 30,39 ) from dual connect by level <= 330;
insert into member
select seq.nextval, 40  from dual connect by level <= 1000; --> popular value
insert into member
select seq.nextval, dbms_random.value( 41,49 ) from dual connect by level <= 200;
insert into member
select seq.nextval, dbms_random.value( 50,59 ) from dual connect by level <= 100;
insert into member
select seq.nextval, dbms_random.value( 60,99 ) from dual connect by level <= 50;

SU   COUNT(*)
-- ----------
10         50
20        270
30        660
40       1200
50        100
60         50



h3.(2) 도수분포 히스토그램

  • 값별로 빈도수{frequency number)를 저장하는 히스토그램


select count(*) , count(distinct age) from member;

  COUNT(*)                      COUNT(DISTINCTAGE)
---------- ---------------------------------------
      2330                                      83

begin
  dbms_stats.gather_table_stats( user, 'MEMBER', method_opt=> 'for all columns size 100' );  
end;

PL/SQL 프로시저가 성공적으로 완료되었습니다.



select num_distinct, num_buckets, histogram
  from user_tab_col_statistics
 where table_name  = 'MEMBER'
   and column_name = 'AGE' ;


                           NUM_DISTINCT                             NUM_BUCKETS HISTOGRAM     
--------------------------------------- --------------------------------------- ---------------
                                     83                                      83 FREQUENCY      




h3.(3) 높이균형 히스토그램

  • 컬럼이 가진 값의 수보다 적은 버킷을 요청할 때 만들어진다.
  • 버킷 개수보다 값의 수가 많기 때문에 하나의 버킷이 여러 개 값을담당
  • 값의 수가 100개인데 10개의 버킷을요청하면하나의 버킷이 평균적으로 10개의 값을 대표한다.
  • 예제 테이블에는 총 2000건이 입력돼있고, 버킷이 20개H 이므로 각 버킷마다 100(2000/20)개 레코드에 해당하는 높이(=빈도수)를 갖는다. 분포는 각 5%씩 이다.


begin
  dbms_stats.gather_table_stats( user, 'MEMBER', method_opt=> 'for all columns size 20' );  
end;

PL/SQL 프로시저가 성공적으로 완료되었습니다.

select num_distinct, num_buckets, histogram
  from user_tab_col_statistics
 where table_name  = 'MEMBER'
   and column_name = 'AGE' ;


                           NUM_DISTINCT                             NUM_BUCKETS HISTOGRAM     
--------------------------------------- --------------------------------------- ---------------
                                     83                                      20 HEIGHT BALANCED


-- endpoint_number : 버킷 변호
-- endpoint3alue   : 버킷이 담당하는 가장 큰 값


select endpoint_number, endpoint_value
  from user_histograms
 where table_name  = 'MEMBER'
   and column_name = 'AGE' 
 order by 1;

                        ENDPOINT_NUMBER                          ENDPOINT_VALUE
--------------------------------------- ---------------------------------------
                                      0                                       1  <- 최소값을 표현하는 용도
                                      1                                      22
                                      2                                      27
                                      3                                      30
                                      4                                      32
                                      5                                      33
                                      6                                      35
                                      7                                      37
                                      8                                      38
                                     16                                      40  <- popular vlaue
                                     17                                      41
                                     18                                      46
                                     19                                      53
                                     20                                      99

==========================================================================================

* endpoint_number=l 벼킷은 1~21 연령대 구간을, endpoint_number= 20 버킷은 56~99 연령대 구간을 대표한다.
* popular vlaue ENDPOINT_NUMBER 8->16 으로 증가된것을 볼수있다. ENDPOINT_NUMBER 가 생략된 형태 
 




"구루비 주주클럽 스터디모임" 에서 2016년에 "오라클 성능 고도화 원리와 해법 II " 도서를 스터디하면서 정리한 내용 입니다.

- 강좌 URL : http://www.gurubee.net/lecture/3353

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입