Oracle/Tuning2018. 11. 8. 15:25

EXPLAIN PLAN 명령어는 PLAN_TABLE에 예상 실행 계획을 저장하고, DBMS_XPLAN.DISPLAY 함수는 해당 테이블을 읽어 실행 계획을 표시한다. PLAN_TABLE이 예전 버전인 경우 Note 항목에 "'PLAN_TABLE' is old version" 메시지가 표시될 수 있다. 관련 내용을 살펴보자.


PLAN_TABLE은 SYS 사용자의 PLAN_TABLE$ 테이블에 대한 PUBLIC 시노님이다.

-- 1
SELECT * FROM all_synonyms WHERE synonym_name = 'PLAN_TABLE';

OWNER  SYNONYM_NAME TABLE_OWNER TABLE_NAME  DB_LINK
------ ------------ ----------- ----------- -------
PUBLIC PLAN_TABLE   SYS         PLAN_TABLE$

1개의 행이 선택되었습니다.

아래는 8.1.7 버전의 PLAN_TABLE 생성 스크립트다. 테스트를 위해 테이블을 생성하자.

-- 2
DROP TABLE plan_table PURGE;

CREATE TABLE plan_table (
    statement_id    VARCHAR2(30)
  , timestamp       DATE
  , remarks         VARCHAR2(80)
  , operation       VARCHAR2(30)
  , options         VARCHAR2(30)
  , object_node     VARCHAR2(128)
  , object_owner    VARCHAR2(30)
  , object_name     VARCHAR2(30)
  , object_instance NUMBER(38)
  , object_type     VARCHAR2(30)
  , optimizer       VARCHAR2(255)
  , search_columns  NUMBER
  , id              NUMBER(38)
  , parent_id       NUMBER(38)
  , position        NUMBER(38)
  , cost            NUMBER(38)
  , cardinality     NUMBER(38)
  , bytes           NUMBER(38)
  , other_tag       VARCHAR2(255)
  , partition_start VARCHAR2(255)
  , partition_stop  VARCHAR2(255)
  , partition_id    NUMBER(38)
  , other           LONG
  , distribution    VARCHAR2(30)
);

실행 계획을 조회하면 Note 항목에 "'PLAN_TABLE' is old version" 메시지가 표시된다.[각주:1]

-- 3
EXPLAIN PLAN FOR SELECT * FROM emp WHERE empno = 7788;

SELECT plan_table_output FROM TABLE (DBMS_XPLAN.DISPLAY ());


PLAN_TABLE_OUTPUT
----------------------------------------------------------------------

----------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost  |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    38 |     1 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    38 |     1 |
|   2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0 |
----------------------------------------------------------------------

Note
-----
   - 'PLAN_TABLE' is old version

12 행이 선택되었습니다.

PUBLIC 시노님이 존재하므로 PLAN_TABLE을 생성할 이유가 없다. PLAN_TABLE을 삭제하자.[각주:2] 실행 계획을 다시 조회하면 CPU Cost, Time, Predicate Information 등의 정보가 표시된다.

-- 4
DROP TABLE PLAN_TABLE PURGE;

EXPLAIN PLAN FOR SELECT * FROM emp WHERE empno = 7788;

SELECT plan_table_output FROM TABLE (DBMS_XPLAN.DISPLAY ());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------
Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    38 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    38 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("EMPNO"=7788)

14 행이 선택되었습니다.


아래에서 느낌표로 표시한 부분이 8.1.7 버전 이후 추가된 항목이다.

-- 5
DESC PLAN_TABLE

 이름              널? 유형
 ----------------- --- --------------
 STATEMENT_ID          VARCHAR2(30)
 PLAN_ID               NUMBER         -- !
 TIMESTAMP             DATE
 REMARKS               VARCHAR2(4000)
 OPERATION             VARCHAR2(30)
 OPTIONS               VARCHAR2(255)
 OBJECT_NODE           VARCHAR2(128)
 OBJECT_OWNER          VARCHAR2(30)
 OBJECT_NAME           VARCHAR2(30)
 OBJECT_ALIAS          VARCHAR2(65)   -- !
 OBJECT_INSTANCE       NUMBER(38)
 OBJECT_TYPE           VARCHAR2(30)
 OPTIMIZER             VARCHAR2(255)
 SEARCH_COLUMNS        NUMBER
 ID                    NUMBER(38)
 PARENT_ID             NUMBER(38)
 DEPTH                 NUMBER(38)     -- !
 POSITION              NUMBER(38)
 COST                  NUMBER(38)
 CARDINALITY           NUMBER(38)
 BYTES                 NUMBER(38)
 OTHER_TAG             VARCHAR2(255)
 PARTITION_START       VARCHAR2(255)
 PARTITION_STOP        VARCHAR2(255)
 PARTITION_ID          NUMBER(38)
 OTHER                 LONG
 OTHER_XML             CLOB           -- !
 DISTRIBUTION          VARCHAR2(30)
 CPU_COST              NUMBER(38)     -- !
 IO_COST               NUMBER(38)     -- !
 TEMP_SPACE            NUMBER(38)     -- !
 ACCESS_PREDICATES     VARCHAR2(4000) -- !
 FILTER_PREDICATES     VARCHAR2(4000) -- !
 PROJECTION            VARCHAR2(4000) -- !
 TIME                  NUMBER(38)     -- !
 QBLOCK_NAME           VARCHAR2(30)   -- !


  1. 주로 서드 파티 툴이 예전 버전의 PLAN_TABLE을 생성했을 때 발생하는 현상이다. [본문으로]
  2. ?/rdbms/admin/utlxplan.sql 스크립트를 실행하라는 의견이 많은데 근본적인 해법은 아니다. [본문으로]
Posted by 정희락_