sample 스키마 scott 계정에서
emp 테이블의 hiredate 조건절에 따라 실행 계획이 다른 이유가 무엇인지 궁금합니다.
첫번째는 테이블 액세스를 합니다.
두번째는 테이블 액세스 후 필터 조건이 추가됩니다.
결론적으로 두번째 실행계획에서 필터 조건이 추가 되는 이유를 모르겠습니다.
SCOTT > select *
2 from emp
3 where hiredate between to_date('20120531', 'yyyymmdd')
4 and to_date('20120601', 'yyyymmdd') + 0.99999 ;
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 38 | 9 (12)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| EMP | 1 | 38 | 9 (12)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("HIREDATE">=TO_DATE(' 2012-05-31 00:00:00', 'syyyy-mm-dd
hh24:mi:ss') AND "HIREDATE"<=TO_DATE(' 2012-06-01 23:59:59',
'syyyy-mm-dd hh24:mi:ss'))
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
695 bytes sent via SQL*Net to client
404 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
SCOTT > select *
2 from emp
3 where hiredate between trunc(sysdate-1) and trunc(sysdate)+0.99999;
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 3896240783
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 38 | 9 (12)| 00:00:01 |
|* 1 | FILTER | | | | | |
|* 2 | TABLE ACCESS FULL| EMP | 1 | 38 | 9 (12)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TRUNC(SYSDATE@!-1)<=TRUNC(SYSDATE@!)+0.99999)
2 - filter("HIREDATE">=TRUNC(SYSDATE@!-1) AND
"HIREDATE"<=TRUNC(SYSDATE@!)+0.99999)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
695 bytes sent via SQL*Net to client
404 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
between 조건은 상식적으로 앞 조건값(v1)이 뒤 조건값(v2)보다 작아야만 하지요.
이를 미리 필터링 하는 것입니다.
상수 조건을 주었을때는 미리 두 값을 비교해
v1 이 v2 보다 작으면 필터가 안붙고
v1 이 v2 보다 크면 이때는 필터가 붙습니다.FILTER(NULL IS NOT NULL)
이때는 아예 쿼리를 실행 안하는거죠(Cost 0)
여기서 상수조건이 아닌 바인드변수 조건을 준다면?
실행계획 수립시 해당 값을 알 수 없으므로 무조건 필터가 붙게 됩니다.
FILTER(v1 <= v2)
Sysdate 는 변하는 값이고 쿼리 수행 전에는 알 수 없는 값이므로
바인드 변수에 준해서 실행계획이 수립되는 듯 합니다.
여기까지 확인되지 않은 제 개인적인 견해였습니다.