2014년 1월 21일 화요일

실행계획의 해석[재직자무료교육/프로그래머교육/구로디지털IT교육,오라클/자바/닷넷/C#/iOS/안드로이드/아이폰교육]

실행계획의 해석[재직자무료교육/프로그래머교육/구로디지털IT교육,오라클/자바/닷넷/C#/iOS/안드로이드/아이폰교육]

실행 계획의 해석
 
 
SELECT STATEMENT                         2       1
    TABLE ACCESS BY INDEX ROWID EMP    2       1
      INDEX UNIQUE SCAN EMP_PK           1     14
 
들여 쓰기가 가장 많이 된 부분이 실행 되므로 EMP_PK 인덱스를 이용하여 인덱스 Unique 검색을 수행하며 찾은 rowid로 TABLE ACCESS가 이루어지므로 2번째와 3번째는 한 단계로 볼 수 있습니다. 즉 같은 수준이 되는 것입니다.

결국 위 SQL 문장은 Primary Key 인덱스를 이용하여 찾은 데이터의 rowid를 이용하여 검색을 수행 한다는 것입니다.
 
다른 예제를 보겠습니다.
 
SQL> conn scott/tiger
연결되었습니다.
 
SQL> select count(*) from emp;
  COUNT(*)
----------
        14
SQL> select count(*) from dept;
  COUNT(*)
----------
         4
 
혹시 이전의 실행 계획이 저장 되어 있을지 몰라 삭제 합니다.
(explain plan 방식을 이용)
 
SQL> delete from plan_table;

SQL> commit;
커밋이 완료되었습니다.
 
EMP Table의 deptno는 인덱스가 결려 있습니다. 오라클은 기본적으로  COST BASED OPTIMIZER 이므로 비용(COST)를 따지게 됩니다. 현재 데이터의 건수가 얼마 되지 않아 인덱스를 이용하는 것보다 테이블을 FULL SCAN하는 것이 효율이 좋아 이를 선택하게 됩니다.
 
SQL>  explain plan
  2   set statement_id = '1'
  3   for
  4   select emp.ename, dept.dname
  5   from emp, dept
  6   where emp.deptno = dept.deptno;
해석되었습니다.

SQL> col  query_plan format a40
 
SQL> select rtrim(lpad(' ',2*level) ||
  2             rtrim(operation) || ' ' ||
  3             rtrim(options) || ' ' || object_name) query_plan ,
  4             cost,
  5             cardinality
  6      from plan_table
  7      start with id=0 and statement_id='1'
  8  connect by prior id = parent_id and statement_id = '1';
 
QUERY_PLAN                                     COST CARDINALITY
---------------------------------------- ---------- -----------
  SELECT STATEMENT                                5          14
    HASH JOIN                                         5          14
      TABLE ACCESS FULL DEPT                      2           4
      TABLE ACCESS FULL EMP                       2          14
 
DEPT 테이블을 FULL SCAN 후 EMP 테이블의 FULL SCAN된 데이터와 HASH JOIN하여 결과를 얻어내게 됩니다.

이번에 옵티마이저 모드를 RULE BASED OPTIMIZER로 변경해 보겠습니다.
 
이 경우에는 전체적인 수행의 비용보다 SQL 문법에 의존적이며 15개 정도 미리 정해져 있는 공식에 따라 가장 빠른 실행 방법이 결정 됩니다. 인덱스가 걸려 있으면 우선적으로 이용하게 되는 거죠… RBO(RULE BASED OPTIMIZER)에서 최 상위의 검색 방법은 ROWID를 이용하는 겁니다, 옵티마이저에 대해서는 추후 강좌에서 자세히 살펴 보겠습니다.
 
SQL> alter session set optimizer_mode = RULE;
세션이 변경되었습니다.
 
SQL> explain plan
  2  set statement_id = '2'
  3  for
  4  select emp.ename, dept.dname
  5  from emp, dept
  6  where emp.deptno = dept.deptno;
해석되었습니다.
 
SQL> col  query_plan format a40
 
SQL> select rtrim(lpad(' ',2*level) ||
  2             rtrim(operation) || ' ' ||
  3             rtrim(options) || ' ' || object_name) query_plan ,
  4             cost,
  5             cardinality
  6      from plan_table
  7      start with id=0 and statement_id='2'
  8  connect by prior id = parent_id and statement_id = '2';
 
QUERY_PLAN                                     COST CARDINALITY
---------------------------------------- ---------- -----------
  SELECT STATEMENT
    TABLE ACCESS BY INDEX ROWID EMP
      NESTED LOOPS
        TABLE ACCESS FULL DEPT
        INDEX RANGE SCAN EMP_DEPTNO
 
이 경우엔 DEPT TABLE을 FULL SCAN(DEPT 테이블이 드라이빙 테이블임)후 EMP Table의 인덱스인 EMP_DEPTNO를 이용하여 RANGE SCAN한 후 NESTED LOOP이므로 DEPT 테이블의 전체 레코드를 한건식 Access하여  EMP Table의 데이터를 ROWID로 얻어 내는 과정을 반복하게 됩니다.
 
다음은 PLAN_TABLE의 컬럼에 대한 설명이니 참고 바랍니다.
 
STATEMENT_ID  explain plan에서 지정한 SQL문을 구별하기 위한 식별자
TIMESTAMP  explain plan 구분을 실행한 시간
REMARKS  주석
OPERATION  각 단계별로 수행할 연산자(HASH JOIN, TABLE ACCESS 등등)
OPTIONS  연산자에 대한 옵션(FULL SACN, RANGE SCAN등등)
OBJECT_NODE  사용된 객체가 참고하는데 사용된 데이터베이스 링크
OBJECT_OWNER  사용된 객체의 소유자
OBJECT_NAME  객체 이름
OBJECT_INSTANCE  원래 SQL문에 있는 FROM절의 객체의 위치를 정수화 한 값
OBJECT_TYPE  객체의 유형
OPTIMIZER  현재의 Optimizer Mode(RULE, CHOOSE, FIRST_ROW…)
SEARCH_COLUMNS  시작과 끝 키를 가진 인덱스 컬럼의 수
ID  실행 계획 각 단계의 ID
PARENT_ID  각 단계의 결과를 가지고 하는 상위 단계 ID
POSITION  두개의 간계가 같은 상위 ID를 가질 때 가장 낮은 ID가 먼저 실행
COST  CBO 에 의해 추정된 현재의 연산 비용
CARDINALITY  현재 연산을 통해 추출 될 레코드 수
BYTES  현재 연산을 통해 추출된 바이트
OTHER_TAG  OTHER 컬럼에서  SQL 텍스트의 기능을 표현
PARTITION_START  파티션 범위 검색 시 시작 파티션
PARTITION_STOP  파티션 범위 검색 시 종료 파티션
PARTITION_ID  파티션 범위 검색 시 시작 파티션과 파티션 범위 검색 시 종료 파티션 컬럼의 값을 계산
OTHER  병렬 실행 슬레이브와 병렬 쿼리에 대한 정보
DISTRIBUTION  병렬 실행 슬레이브가 어떻게 레코드를 추출하는가의 방법
CPU_COST  사용자 정의 CPU 비용
IO_COST  사용자 정의 IO 비용
 

  • 자바
  • 오라클/빅데이터
  • 아이폰/안드로이드
  • 닷넷/WPF
  • 표준웹/HTML5
  • 채용/취업무료교육
  • 초보자코스

  • 댓글 없음:

    댓글 쓰기