[관리] Oracle EXPLAIN PLAN(실행계획) 세우기

Oracle EXPLAIN PLAN(실행계획) 세우기

SQL문의 실행계획을 보면 비효율이 발생한 원인을 알 수 있고 좋은 실행계획이

수립될 수 있도록 하는 방법을 찾을 수 있다. 이러한 실행계획을 자주 참조하는

것이 바로 옵티마이저를 이해할 수 있는 최선책이며, SQL문장을 튜닝할 수 있는

능력을 키울 수 있는 가장 좋은 방법이다.

사용자들이 SQL문의 액세스 경로를 확인하고 튜닝을 할 수 있도록 SQL문을 분석하고

해석하여 실행계획을 수립한 후 실행계획을 테이블(Plan_table)에 저장하도록 해준다.

EXPLAIN PLAN 명령은 오라클 옵티마이저에 의해서 SELECT, UPDATE, INSERT 그리고

DELETE문의 실행계획을 보여준다.

실행계획은 데이타를 축출하기 위해 오라클이 SQL 문장을 차례로 실행하는

작업 방법을 말한다.

– EXPLAIN PLAN 실습 Spool File

우선 $ORACLE_HOME/rdbms/admin/utlxplan.sql 이라는 스크립트를 실행하여

PLAN_TABLE 테이블을 생성한다.

SQL> truncate table plan_table;

Table truncated.

SQL> explain plan for

  2  select ename, sal

  3  from scott.emp, scott.dept

  4  where emp.deptno = dept.deptno;

Explained.

SQL> select operation, options, object_name, id parent_id

  2  from plan_table;

OPERATION         OPTIONS      OBJECT_NAME    PARENT_ID

—————– ———— ————- ———-

SELECT STATEMENT                                      0

NESTED LOOPS                                          1

TABLE ACCESS      FULL         EMP                    2

INDEX             UNIQUE SCAN  PK_DEPT                3

SQL> truncate table plan_table;

Table truncated.

SQL> select * from dept;

    DEPTNO DNAME          LOC

———- ————– ————-

        10 ACCOUNTING     NEW YORK

        20 RESEARCH       DALLAS

        30 SALES          CHICAGO

        40 OPERATIONS     BOSTON

SQL> explain plan for

  2  select emp.ename, emp.sal, dept.loc

  3  from scott.emp, scott.dept

  4  where emp.deptno = dept.deptno;

Explained.

SQL> select operation, options, object_name, id parent_id

  2  from plan_table;

OPERATION         OPTIONS OBJECT_NAME   PARENT_ID

—————– ——- ———— ———-

SELECT STATEMENT                                0

HASH JOIN                                       1

TABLE ACCESS      FULL    DEPT                  2

TABLE ACCESS      FULL    EMP                   3

                          

SQL> /                    

                          

OPERATION         OPTIONS OBJECT_NAME   PARENT_ID

—————– ——- ———— ———-

SELECT STATEMENT                                0

HASH JOIN                                       1

TABLE ACCESS      FULL    DEPT                  2

TABLE ACCESS      FULL    EMP                   3

SQL> set autotrace on

SQL> select ename, sal

  2  from scott.emp, scott.dept

  3  where emp.deptno = dept.deptno;

ENAME             SAL

———- ———-

SMITH             800

ALLEN            1600

WARD             1250

JONES            2975

MARTIN           1250

BLAKE            2850

CLARK            2450

SCOTT            3000

KING             5000

TURNER           1500

ADAMS            1100

JAMES             950

FORD             3000

MILLER           1300

14 rows selected.

Execution Plan

———————————————————-

   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=14 Bytes=168)

   1    0   NESTED LOOPS (Cost=1 Card=14 Bytes=168)

   2    1     TABLE ACCESS (FULL) OF ‘EMP’ (Cost=1 Card=14 Bytes=140)

   3    1     INDEX (UNIQUE SCAN) OF ‘PK_DEPT’ (UNIQUE)

Statistics

———————————————————-

          0  recursive calls

         12  db block gets

          8  consistent gets

          3  physical reads

          0  redo size

       1064  bytes sent via SQL*Net to client

        425  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          2  sorts (memory)

          0  sorts (disk)

         14  rows processed

SQL> select operation, options, object_name, id parent_id

  2  from plan_table;

OPERATION         OPTIONS  OBJECT_NAME   PARENT_ID

—————– ——– ———— ———-

SELECT STATEMENT                                 0

HASH JOIN                                        1

TABLE ACCESS      FULL     DEPT                  2

TABLE ACCESS      FULL     EMP                   3

Execution Plan

———————————————————-

   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=6 Bytes=144)

   1    0   TABLE ACCESS (FULL) OF ‘PLAN_TABLE’ (Cost=1 Card=6 Bytes=144)

Statistics

———————————————————-

          0  recursive calls

          4  db block gets

          2  consistent gets

          0  physical reads

          0  redo size

        731  bytes sent via SQL*Net to client

        425  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          4  rows processed

SQL> 1

  1* select operation, options, object_name, id parent_id

SQL> c/id/id,

  1* select operation, options, object_name, id, parent_id

SQL> l

  1  select operation, options, object_name, id, parent_id

  2* from plan_table

SQL> /

OPERATION         OPTIONS  OBJECT_NAME          ID  PARENT_ID

—————– ——– ———— ———- ———-

SELECT STATEMENT                                 0

HASH JOIN                                        1          0

TABLE ACCESS      FULL     DEPT                  2          1

TABLE ACCESS      FULL     EMP                   3          1

Execution Plan

———————————————————-

   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=6 Bytes=162)

   1    0   TABLE ACCESS (FULL) OF ‘PLAN_TABLE’ (Cost=1 Card=6 Bytes=162)

Statistics

———————————————————-

          0  recursive calls

          4  db block gets

          2  consistent gets

          0  physical reads

          0  redo size

        795  bytes sent via SQL*Net to client

        425  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          1  sorts (memory)

          0  sorts (disk)

          4  rows processed

SQL> set autotrace off

SQL> select operation, options, object_name, id, parent_id

  2  from plan_table;

OPERATION         OPTIONS  OBJECT_NAME          ID  PARENT_ID

—————– ——– ———— ———- ———-

SELECT STATEMENT                                 0

HASH JOIN                                        1          0

TABLE ACCESS      FULL     DEPT                  2          1

TABLE ACCESS      FULL     EMP                   3          1

SQL> set autotrace on

SQL> select ename, sal

  2  from scott.emp, scott.dept

  3  where emp.deptno = dept.deptno;

ENAME             SAL

———- ———-

SMITH             800

ALLEN            1600

WARD             1250

JONES            2975

MARTIN           1250

BLAKE            2850

CLARK            2450

SCOTT            3000

KING             5000

TURNER           1500

ADAMS            1100

JAMES             950

FORD             3000

MILLER           1300

14 rows selected.

Execution Plan

———————————————————-

   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=14 Bytes=168)

   1    0   NESTED LOOPS (Cost=1 Card=14 Bytes=168)

   2    1     TABLE ACCESS (FULL) OF ‘EMP’ (Cost=1 Card=14 Bytes=140)

   3    1     INDEX (UNIQUE SCAN) OF ‘PK_DEPT’ (UNIQUE)

Statistics

———————————————————-

          0  recursive calls

         12  db block gets

          8  consistent gets

          0  physical reads

          0  redo size

       1064  bytes sent via SQL*Net to client

        425  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

         14  rows processed

SQL> set autotrace off

SQL> select operation, options, object_name, id, parent_id

  2  from plan_table;

OPERATION         OPTIONS  OBJECT_NAME          ID  PARENT_ID

—————– ——– ———— ———- ———-

SELECT STATEMENT                                 0

HASH JOIN                                        1          0

TABLE ACCESS      FULL     DEPT                  2          1

TABLE ACCESS      FULL     EMP                   3          1

SQL> select emp.ename, emp.sal, dept.loc

  2  from scott.emp, scott.dept

  3  where emp.deptno = dept.deptno;

ENAME             SAL LOC

———- ———- ————-

SMITH             800 DALLAS

ALLEN            1600 CHICAGO

WARD             1250 CHICAGO

JONES            2975 DALLAS

MARTIN           1250 CHICAGO

BLAKE            2850 CHICAGO

CLARK            2450 NEW YORK

SCOTT            3000 DALLAS

KING             5000 NEW YORK

TURNER           1500 CHICAGO

ADAMS            1100 DALLAS

JAMES             950 CHICAGO

FORD             3000 DALLAS

MILLER           1300 NEW YORK

14 rows selected.

SQL> select operation, options, object_name, id, parent_id

  2  from plan_table;

OPERATION         OPTIONS  OBJECT_NAME          ID  PARENT_ID

—————– ——– ———— ———- ———-

SELECT STATEMENT                                 0

HASH JOIN                                        1          0

TABLE ACCESS      FULL     DEPT                  2          1

TABLE ACCESS      FULL     EMP                   3          1

SQL> set autotrace on

SQL> select emp.ename, emp.sal, dept.loc

  2  from scott.emp, scott.dept

  3  where emp.deptno = dept.deptno;

ENAME             SAL LOC

———- ———- ————-

SMITH             800 DALLAS

ALLEN            1600 CHICAGO

WARD             1250 CHICAGO

JONES            2975 DALLAS

MARTIN           1250 CHICAGO

BLAKE            2850 CHICAGO

CLARK            2450 NEW YORK

SCOTT            3000 DALLAS

KING             5000 NEW YORK

TURNER           1500 CHICAGO

ADAMS            1100 DALLAS

JAMES             950 CHICAGO

FORD             3000 DALLAS

MILLER           1300 NEW YORK

14 rows selected.

Execution Plan

———————————————————-

   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=14 Bytes=266)

   1    0   HASH JOIN (Cost=3 Card=14 Bytes=266)

   2    1     TABLE ACCESS (FULL) OF ‘DEPT’ (Cost=1 Card=4 Bytes=36)

   3    1     TABLE ACCESS (FULL) OF ‘EMP’ (Cost=1 Card=14 Bytes=140)

Statistics

———————————————————-

          0  recursive calls

         24  db block gets

         11  consistent gets

          0  physical reads

          0  redo size

       1253  bytes sent via SQL*Net to client

        425  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

         14  rows processed

SQL> set autotrace on explain

SQL> select emp.ename, emp.sal, dept.loc

  2  from scott.emp, scott.dept

  3  where emp.deptno = dept.deptno;

ENAME             SAL LOC

———- ———- ————-

SMITH             800 DALLAS

ALLEN            1600 CHICAGO

WARD             1250 CHICAGO

JONES            2975 DALLAS

MARTIN           1250 CHICAGO

BLAKE            2850 CHICAGO

CLARK            2450 NEW YORK

SCOTT            3000 DALLAS

KING             5000 NEW YORK

TURNER           1500 CHICAGO

ADAMS            1100 DALLAS

JAMES             950 CHICAGO

FORD             3000 DALLAS

MILLER           1300 NEW YORK

14 rows selected.

Execution Plan

———————————————————-

   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=14 Bytes=266)

   1    0   HASH JOIN (Cost=3 Card=14 Bytes=266)

   2    1     TABLE ACCESS (FULL) OF ‘DEPT’ (Cost=1 Card=4 Bytes=36)

   3    1     TABLE ACCESS (FULL) OF ‘EMP’ (Cost=1 Card=14 Bytes=140)

SQL> select emp.ename, emp.sal, dept.loc

  2  from scott.emp, scott.dept

  3  where emp.deptno = dept.deptno;

ENAME             SAL LOC

———- ———- ————-

SMITH             800 DALLAS

ALLEN            1600 CHICAGO

WARD             1250 CHICAGO

JONES            2975 DALLAS

MARTIN           1250 CHICAGO

BLAKE            2850 CHICAGO

CLARK            2450 NEW YORK

SCOTT            3000 DALLAS

KING             5000 NEW YORK

TURNER           1500 CHICAGO

ADAMS            1100 DALLAS

JAMES             950 CHICAGO

FORD             3000 DALLAS

MILLER           1300 NEW YORK

14 rows selected.

Execution Plan

———————————————————-

   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=14 Bytes=266)

   1    0   HASH JOIN (Cost=3 Card=14 Bytes=266)

   2    1     TABLE ACCESS (FULL) OF ‘DEPT’ (Cost=1 Card=4 Bytes=36)

   3    1     TABLE ACCESS (FULL) OF ‘EMP’ (Cost=1 Card=14 Bytes=140)

SQL> alter session set optimizer_mode = rule;

Session altered.

SQL> select emp.ename, emp.sal, dept.loc

  2  from scott.emp, scott.dept

  3  where emp.deptno = dept.deptno;

ENAME             SAL LOC

———- ———- ————-

SMITH             800 DALLAS

ALLEN            1600 CHICAGO

WARD             1250 CHICAGO

JONES            2975 DALLAS

MARTIN           1250 CHICAGO

BLAKE            2850 CHICAGO

CLARK            2450 NEW YORK

SCOTT            3000 DALLAS

KING             5000 NEW YORK

TURNER           1500 CHICAGO

ADAMS            1100 DALLAS

JAMES             950 CHICAGO

FORD             3000 DALLAS

MILLER           1300 NEW YORK

14 rows selected.

Execution Plan

———————————————————-

   0      SELECT STATEMENT Optimizer=RULE

   1    0   NESTED LOOPS

   2    1     TABLE ACCESS (FULL) OF ‘EMP’

   3    1     TABLE ACCESS (BY INDEX ROWID) OF ‘DEPT’

   4    3       INDEX (UNIQUE SCAN) OF ‘PK_DEPT’ (UNIQUE)

SQL> select /*+ all_rows */ emp.ename, emp.sal, dept.loc

  2  from scott.emp, scott.dept

  3  where emp.deptno = dept.deptno;

ENAME             SAL LOC

———- ———- ————-

SMITH             800 DALLAS

ALLEN            1600 CHICAGO

WARD             1250 CHICAGO

JONES            2975 DALLAS

MARTIN           1250 CHICAGO

BLAKE            2850 CHICAGO

CLARK            2450 NEW YORK

SCOTT            3000 DALLAS

KING             5000 NEW YORK

TURNER           1500 CHICAGO

ADAMS            1100 DALLAS

JAMES             950 CHICAGO

FORD             3000 DALLAS

MILLER           1300 NEW YORK

14 rows selected.

Execution Plan

———————————————————-

   0      SELECT STATEMENT Optimizer=HINT: ALL_ROWS (Cost=3 Card=14 Bytes=266)

   1    0   HASH JOIN (Cost=3 Card=14 Bytes=266)

   2    1     TABLE ACCESS (FULL) OF ‘DEPT’ (Cost=1 Card=4 Bytes=36)

   3    1     TABLE ACCESS (FULL) OF ‘EMP’ (Cost=1 Card=14 Bytes=140)

서진우

슈퍼컴퓨팅 전문 기업 클루닉스/ 상무(기술이사)/ 정보시스템감리사/ 시스존 블로그 운영자

You may also like...

페이스북/트위트/구글 계정으로 댓글 가능합니다.