explain plan for
select *
from t2,
(select /*+ dynamic_sampling(t1 4) */
c1, c2
from t1
where t1.c2 = 'A' and
t1.c3 = 'b'
) v
where t2.c1 = v.cl;
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 16 | 9 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 16 | 9 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | T1 | 1 | 8 | 7 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | T2_N1 | 1 | | 1 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID| T2 | 1 | 8 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
T1 access시 Rows가 1로 정확한 cardinality가 계산됨
1. 조건절에 literal 값이 오지 않는 경우
select
*
from
t1
where
c2 = 'A' and
c3 = (select max(c2) from t3)
;
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5000 | 40000 | 10 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL | T1 | 5000 | 40000 | 7 (0)| 00:00:01 |
| 2 | SORT AGGREGATE | | 1 | 2 | | |
| 3 | TABLE ACCESS FULL| T3 | 2 | 4 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
2. 바인드 변수의 사용 혹은 조인이 사용된 경우
select
*
from
t1, t2
where
t1.c1 = t2.c1+100000
;
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11000 | 171K| 15 (7)| 00:00:01 |
|* 1 | HASH JOIN | | 11000 | 171K| 15 (7)| 00:00:01 |
| 2 | TABLE ACCESS FULL| T1 | 11000 | 88000 | 7 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| T2 | 11000 | 88000 | 7 (0)| 00:00:01 |
---------------------------------------------------------------------------
1. hard parse 시의 오버헤드가 증가한다. (테이블의 블록을 물리적으로 읽어 샘플링을 수행해야 하기 때문이다.)
2. bind 변수 사용시 동작하지 않는다.(bind peeking이 비활성화 되어 있다면 더더욱)
3. DSS용으로 고안된 방법이다.
4. 쿼리 레벨이 아닌 테이블 레벨로 이루어진다.(조인이나 서브쿼리와 같은 복잡한 조건은 처리하지 못한다.)
dynamic sampling은 통계정보가 없는 테이블에 대한 쿼리를 도와주는 역할뿐만 아니라 위와 같이 통계 정보에 대한 해석의 오류에서 오는 실행 계획 이상 현상을 방지할 수 있는 훌륭한 도구가 될 수 있다.