grant advisor to bshman
SQL> VARIABLE tn VARCHAR2(30);
SQL> DECLARE
2 l_sqltext CLOB := 'select count(*) from bshman_test where col1 < 100 and col3 < 100' ;
3 BEGIN
4 :tn := dbms_sqltune.create_tuning_task(sql_text=>l_sqltext) ;
5 dbms_sqltune.execute_tuning_task(:tn) ;
6 END;
7 /
PL/SQL 처리가 정상적으로 완료되었습니다.
경 과: 00:02:03.32
SQL>
SQL>
SQL> print TN
TN
--------------------------------
작업_1291
SQL> set long 20000
SQL> select dbms_sqltune.report_tuning_task(:tn) from dual;
DBMS_SQLTUNE.REPORT_TUNING_TASK(:TN)
--------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : 작업_1291
Tuning Task Owner : BSHMAN
Scope : COMPREHENSIVE
Time Limit(seconds) : 1800
Completion Status : COMPLETED
Started at : 11/16/2012 22:14:52
Completed at : 11/16/2012 22:16:55
Number of Index Findings : 1
DBMS_SQLTUNE.REPORT_TUNING_TASK(:TN)
--------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Schema Name: BSHMAN
SQL ID : dz3t6d8yccm38
SQL Text : select count(*) from bshman_test where col1 < 100 and col3 < 100
-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------
1- Index Finding (see explain plans section below)
--------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK(:TN)
--------------------------------------------------------------------------------
이 명령문의 실행 계획은 하나 이상의 인덱스를
Recommendation (estimated benefit: 100%)
----------------------------------------
-Access Advisor를 실행하여 물리적 스키마 설계를 향상시키거나 권장
create index BSHMAN.IDX$$_050B0001 on BSHMAN.BSHMAN_TEST('COL1');
Rationale
---------
권장 인덱스를 생성하면 이 명령문의 실행 계획이 크게 향상됩니다. 하지만 단
"Access Advisor"를 실행하는 것이 더 좋을 수 있습니다. 이렇게 하면 인덱스 유
DBMS_SQLTUNE.REPORT_TUNING_TASK(:TN)
--------------------------------------------------------------------------------
고려한 포괄적인 인덱스 권장 사항을
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
1- Original
-----------
Plan hash value: 2702808718
----------------------------------------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK(:TN)
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 8378 (3)| 00:01:41 |
| 1 | SORT AGGREGATE | | 1 | 8 | | |
|* 2 | TABLE ACCESS FULL| BSHMAN_TEST | 3 | 24 | 8378 (3)| 00:01:41 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK(:TN)
--------------------------------------------------------------------------------
2 - filter("COL1"<100 AND "COL3"<100)
2- Using New Indices
--------------------
Plan hash value: 2810742563
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK(:TN)
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 5 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 8 | | |
|* 2 | TABLE ACCESS BY INDEX ROWID| BSHMAN_TEST | 3 | 24 | 5 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | IDX$$_050B0001 | 3 | | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK(:TN)
--------------------------------------------------------------------------------
2 - filter("COL3"<100)
3 - access("COL1"<100)
-------------------------------------------------------------------------------
경 과: 00:00:00.48
select * from 사원 where 직급 = '부장' and 연봉 >= 5000;
-- 직급이 [부장, 과장, 대리, 사원] 의 집합이고 각각 25%의 비중을 갖는다.
-- 전체 사원이 1000명이고 히스토그램상 '연봉 >= 5000' 조건에 부합하는 사원 비중이 10%이면, 옵티마이저는
-- 위 쿼리 조건에 해당하는 사원 수를 25(=1000*0.25*0.1)명으로 추정한다.
-- 하지만, 직급과 연봉 간에 상관관계가 매우 높아서 만약 모든 부장의 연봉이 5000만원 이상이라면 실제 위 쿼리 결과는
-- 250(=1000*0.25*1)건이다.
-- 사원 급여와 상여금 간에도 상관관계가 매우 높다.
-- 이러한 이유 때문에 카디널리티가 잘못 계산되면 다른 집합과 여러 번 조인을 거치는 동안 카디널리티는 점점
-- 부정확해지고 궁극적으로 옵티마이저가 잘못된 실행계획을 수립하는 결과를 낳는다.
-- 9i 부터 동적 샘플링으로 해결하려고 하고있지만
-- 동적 샘플링 레벨을 4이상일때만 작동한다.
-- 또한 11g부터는 사용자가 지정한 컬럼들에 대해 결합 선택도를 미리 수집해 두는 기능을 제공하는데
-- 이러한 기능은 6절5항 (429p 결합산정도에서 확인가능)
create table t
as
select rownum a, rownum b from dual
connect by level <= 10000;
create index t_x01 on t(a);
create index t_x02 on t(b);
exec dbms_stats.gather_table_stats(user,'t');
SQL> set autotrace traceonly exp
SQL> select * from t where a = 1 and b =1;
경 과: 00:00:00.00
Execution Plan
----------------------------------------------------------
Plan hash value: 481254278
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 7 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_X01 | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("B"=1)
2 - access("A"=1)
-- 인덱스를 t_x01 에서 t_x03으로 변경
alter index t_x01 rename to t_x03
SQL> select * from t where a = 1 and b =1;
경 과: 00:00:00.00
Execution Plan
----------------------------------------------------------
Plan hash value: 632348571
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 7 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_X02 | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A"=1)
2 - access("B"=1)
order_pk : 고객번호 + 주문일자
order_n01 : 고객번호 + 주문일자
같은 조건이라면 당연 pk를 타는게 맞지만,
알파벳순서로 n01 인덱스를 탄다.
- 강좌 URL : http://www.gurubee.net/lecture/3277
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.