핵심 공식!!
Cardinality = Base Cardinality * Selectivity
1200명의 청중을 대상으로 이 중에 몇 명이 12월에 태어났겠느냐 물었을 때 CBO적으로 답을 구하는 행동 | {code:sql}select count(*) from auudience 청중 where month_no = 12{code} | ||
1년은 12달이다 | 알려진 사실 | ||
생일은(아마도) 년 중 고르게 분산되어 있을것이다. | 가정 | density or 1/NDV | user_tab_col_statistics.num_distinct = 12 |
청중의 1/12는 어느 특정 월에 태어났을 것이다. | 월의 선택도 | selectivity | user_tab_col_statistics.num_density = 1/12 user_ab_histogram=popular histogram 같은 분포를 가진다. (차라리 히스토그램이 없어서 1/ndv를 사용했다라고하자) |
어느 특정 월을 요청하였다. | 조건 | predicate | month_no=12 |
요청한 월은 실제로 달력에 존재한다. | 경계체크 | month_no=12는 user_tab_col_statistics의 low_value와 high_vlaue사이에 있다. user_tab_col_statistics.num_null = 0 | |
청중은 1200명이다. | 기본 카디널리티 | base cardinality | user_tables.num_rows=1200 |
정답은 1200명의 1/12/인 100명이다. | 계산된 카디날리티 | adjust cardinality | count(*)= 100 |
-- 온라인코드집(birth_month_01.sql)을 보면 Test의 단순성을 위해서인지 _optimizer_cost_model을 io로 설정했고, 히스토그램 없이 통계정보를 수집했다
create table audience as
selec trunc(dbms_random.value(1,13)) month_no
from all_objects
wher rownum <= 1200
;
begin
dbms_stats.gather_table_stats(
user,
'audience',
cascade => true,
estimate_percent => null,
method_opt => 'for all columns size 1'
);
end;
/
set autotrace traceonly explain
select count(*)
from audience
where month_no = 12
;
select count(*)
from auudience 청중
where month_no = 12
density or 1/NDV | user_tab_col_statistics.num_distinct = 12 |
selectivity | user_tab_col_statistics.num_density = 1/12 user_tab_histogram=popular histogram 같은 분포를 가진다. (차라리 히스토그램이 없어서 1/ndv를 사용했다라고하자) |
predicate | month_no=12 |
num_nulls | month_no=12는 user_tab_col_statistics의 low_value와 high_vlaue사이에 있다. user_tab_col_statistics.num_nulls = 0 -> user_tab_col_statistics.num_null = 120 |
base cardinality | user_tables.num_rows=1200 |
조정된 Cardinality
Update audience
Set month = null
Where rowed in (select rid
From (select rowed rid,
, ntil(10) over () nt
From audience)
Where nt = 10);
Commit;
begin
dbms_stats.gather_table_stats(
user,
'audience',
cascade => true,
estimate_percent => null,
method_opt => 'for all columns size 1'
);
end;
/
set autotrace traceonly explain
select count(*)
from audience
where month_no = 12
;?
리터럴을 사용한 범위검색 시의 비공식적인 알고리즘
Selectivity = '요청한 범위' / '전체 대상 범위'
조건이 두개인 쿼리의 일반적인 선택도 계산방법"
※ 오류의 가능성
- 강좌 URL : http://www.gurubee.net/lecture/3976
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.