두 실행계획이 서로 다른 이유가 무엇때문인지 알수가 없네요..;; 0 2 2,691

by 제로 [2012.06.01 14:40:26]


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

by 마농 [2012.06.01 16:10:33]

between 조건은 상식적으로 앞 조건값(v1)이 뒤 조건값(v2)보다 작아야만 하지요.
이를 미리 필터링 하는 것입니다.


상수 조건을 주었을때는 미리 두 값을 비교해
v1 이 v2 보다 작으면 필터가 안붙고
v1 이 v2 보다 크면 이때는 필터가 붙습니다.FILTER(NULL IS NOT NULL)
이때는 아예 쿼리를 실행 안하는거죠(Cost 0)


여기서 상수조건이 아닌 바인드변수 조건을 준다면?
실행계획 수립시 해당 값을 알 수 없으므로 무조건 필터가 붙게 됩니다.
FILTER(v1 <= v2)


Sysdate 는 변하는 값이고 쿼리 수행 전에는 알 수 없는 값이므로
바인드 변수에 준해서 실행계획이 수립되는 듯 합니다.


여기까지 확인되지 않은 제 개인적인 견해였습니다.


by 제로 [2012.06.01 17:15:15]

아~ 그렇군요...
왜 필터가 추가로 생긴는지에 대한 궁금증이 풀린것 같습니다.
감사합니다~ㅎㅎ
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입