옵티마이저가 최적의 실행계획을 생성할 수 있도록 제공해주는 테이블(객체) 및 시스템 분석정보
객체 통계 : talble, column, index
시스템 통계 : host의 CPU와 I/O Time에 대한 통계
자동
DB 생성시 maintenance autotask 설정에 의해(statistics_level=typical 또는 all) 매일 객체 통계수집이 실행되고 있음
새로 수집된 통계는 DD에 overwrite되며 이전 통계는 30일치를 저장하고 있음
통계가 empty(dynamic sampling을 해야 함) 또는 state(마지막 수집 후 10% 이상 변경됨)을 대상으로 수집
gather_database_stats의 파라미터들
개별적인 테이블들의 특성을 입력하여 통계를 수집할 수 있도록 파라미터 설정
입력된 파라미터들을 저장
cascade : 테이블을 만들 때, 인덱스 통계도 만들라는 의미 -> estimate persent가 정해져 있어서 일정량마다 통계를 만들게 되므로 index 통계가 정확했으면 하는 경우 cascade를 no로 하고 한꺼번에 제작할 수 있음
no_invalidate : 만들어진 통계를 즉시 data dictionary에 넣게 되는데 이때 새로 만들어진 통계에 의해 shared pool의 parsing된 것들이 모두 incalidate되어 성능이 떨어지게 됨, 이 파라미터를 설정하면 즉시 게시하지 않음 -> auto 가 default(5시간에 한 번 게시)
granularity : 얼마나 나눠서 통계를 수집할 것인지
incremental : 파티션을 합쳐서 만들것인지
stale_percent : 설정한 만큼의 변경이 일어난 것만 통계 수집
dba_tab_stat_prefs에서 조회 가능
publish : 통계를 딕셔너리에 게시할 것인지, 아니면 이전 보류 영역에 저장할 것인지 결정
옵티마이저 통계 환경설정
select * from dba_tab_stat_prefs; - 설정 내용 확인
exec dbms_stats.set_table_perfs('SH','SALES','STALE_PERCENT',13); - 설정
select dbms_stats.get_perfs('STALE_PERCENT','SH','SALES') from dual; - 설정 내용 확인
통계 환경설정 : db전체, schema, table level에 특성에 맞는 통계환경 설정을 할 수 있음
옵티마이저 통계 유형
시스템 통계
NoWorkload
workload : 데이터 베이스의 작업량에 따라 통계를 냄
CPU 속도 CPUSPEEDNW
IOSEEKTIM
IOTFRSPEED -- Noworkload
평균 SBIO time SREADTIM -- 이하는 Workload 1/1000 초 ms
평균 MBIO time MREADTIM
평균 MBRC MBRC
CPUSPEED
MAXTHR IO 서브시스템의 최대처리량 -초당 바이트
SLAVETHR 병렬슬레이브의 평균처리량
테이블 통계(DBA_TAB_STATISTICS)
인덱스 통계
null값을 뺀 저장된 행의 갯수
BLEVEL : 최하위 블록 조회 비용을 계산하는데 사용되며 루트 블록에서 최하위 블록까지의 인덱스 깊이를 나타냄
-> Nested Loops Join을 사용하게 하면 반복적인 Inner Table의 접근으로 I/O가 크게 증가할 수 있음
swap_join_input() 힌트를 사용하여 driving을 바꿀 수 있음
Subquery
Nested Subquery : where 절에 사용되는 subquery
Subquery unnesting(괄호를 풂) -> 서브 쿼리로 작성되었지만 조인 방식으로 해결될 수 있음
Single Row Subquery
사원 141의 job_id와 동일한 job_id를 가진 사원을 출력 -> where job_id = (select job_id from employees where employee_id = 141);
Multiple row subquery
각 부서의 최소 급여와 같은 급여를 받는 사원들의 이름과 급여 출력 -> where salary = (select min(salary) from employees group by department_id); -> 단일 행 하위 질의에 2개 이상의 행이 리턴되었다는 error 발생
= 대신 in을 사용 -> 각 부서별로 최소 급여를 받는 사원이 나오지 않고 다른 부서의 값과 같은 값을 가지는 사원들까지 모두 나오게 됨 -> multi culmn subquery를 사용해야 정확한 결과가 나옴
Multiple Column Subquery
pairwise(쌍 비교) 방식 - where (department_id, empno) in (...)
non-Pairwise 방식 - where department_id in (...) and empno in (...)
Correlated subquery(상관 서브 쿼리)
메인 쿼리의 컬럼 값이 서브 쿼리 안에서 비교되는 경우
Inline View : from 절에 나타나는 subquery
Simple View
View Merging : 결과 값들이 결합됨
조건절과 조인문만을 포함
Complex View
group by, distinct를 포함하는 view
Non-mergeable View
Merging이 불가능
Scalar Subquery : 하나의 컬럼 값 하나를 리턴
딱 하나의 값만을 리턴해야 하는 쿼리
select 문 안의 서브 쿼리는 여러 값이 아닌 단 하나의 값이 나와야 사용 가능
Subquery Tuning
exists : 존재하는 값이 하나라도 있으면 결과를 출력하기 때문에 테이블을 하나하나 읽다가도 앞부분에 원하는 값이 존재한다면 index를 사용하는 것보다 더 빠른 성능을 보일 수도 있음