'EXPLAIN PLAN'에 해당되는 글 2건

  1. 2010.01.12 EXPLAIN PLAN(실행계획) 이란
  2. 2009.03.27 toad 에서 explain plan 보기 1
ORACLE/TUNING2010. 1. 12. 15:45
반응형

EXPLAIN PLAN(실행계획) 이란?

 

 

SQL문의 엑세스 경로를 확인하고 튜닝할 수 있도록 SQL문을 분석하고 해석하여

   실행계획을 수립한 후 실행계획을 PLAN_TABLE에 저장하도록 해주는 명령 입니다.

 

SQL  Trace없이 사용 할 수 있습니다.

 

ORACLE_HOME/rdbms/admin/utlxplan.sql실행

 

statement_id컬럼에 인덱스를 생성해주는것이 수행속도를 향상시켜주고 

    id값이 중복되는 것을 막을 수 있습니다.

 

[Syntax]

 

 

 - statement_id = 'identifiedr' : 1-30자로 부여할 수 있는 해당 실행문의 제목

 - INTO tablename : 출력문을 저장하는 테이블명 PLAN_TABLE을 사용하지 않을경우 사용

 - FOR statement : 실행계획을 수립하고자 하는 SQL(SELECT, INSERT, DELETE, UPDATE)

 

 

 

 

 

1. Plan_table 생성

 

  Explain plan sql에 포함해서 수행하면 옵티마이저가 실행 계획까지만 수립하여

     plan_table에 저장해 둡니다.

  table을 생성하기 위한 script ORACLE_HOME/rdbms/admin/utlxplan.sql 입니다.

 

SQL>@C:\oracle\ora81\rdbms\admin\utlxplan.sql

 

테이블이 생성되었습니다.

 

 

 

 

 

2. Index 생성

 

◈ 테이블 생성 후 수행 속도 향상과 동일한 statement_id가 생성되는 것을  방지하기 위해 

    index를 생성 합니다.

 

SQL> CREATE UNIQUE INDEX plan_index ON PLAN_TABLE(statement_id,id);

 

인덱스가 생성되었습니다.

 

 

 

 

 

3. SQL 문 사용

 

FOR 뒷 부분에 확인하고자 하는 sql을 입력 합니다.

 

SQL>EXPLAIN PLAN SET STATEMENT_ID='a1' FOR

       SELECT /*+ index(emp emp_pk) */ * FROM emp WHERE empno > 0;

 

해석되었습니다.

 

 

 

 

 

4. PLAN_TABLE SELECT 하는 SQL 문을 실행

 

  plan.sql이라고 저장해서 사용하면 편리합니다.

 

SQL>SELECT LPAD(operation,LENGTH(operation)+ 2*(LEVEL-1)) ||DECODE(id,0,'cost  estimate:' ||

       DECODE(position,'0','N/A',position),null) || ' ' ||options || DECODE(object_name,null,null,':') ||

       RPAD(object_owner, LENGTH(object_name)+1,',') || object_name ||

       DECODE (object_type,'UNIQUE' ,'(U) ','NON_UNIQUE','(NU)',null) ||

       DECODE(object_instance,null,null,'('||object_instance||')')  "Explain Plan"

       FROM PLAN_TABLE

       START WITH ID= 0 and STATEMENT_ID = '&&id'

       CONNECT by prior ID=PARENT_ID and STATEMENT_ID='&&id'

 

 

a1을 입력하면 아래와 같은 실행계획을 볼 수 있습니다.

 

 Explain Plan

-----------------------------------------------

 

SELECT STATEMENTcost  estimate:1

  TABLE ACCESS BY INDEX ROWID:TESTEMP(1)

    INDEX RANGE SCAN:TEST,,,EMP_PK

 

 

 

 

 

PLAN_TABLE 컬럼 설명

 

 ------------------------------------------------------------------------------------------------

 컬 럼 명                                       

 ------------------------------------------------------------------------------------------------

 STATEMENT_ID                                EXPLAIN PLAN문에서 사용자가 지정한 제목

 TIMESTAMP                            실행계획이 수립된 날짜와 시간

 REMARKS                                     사용자가 부여한 주석(COMMENT)

 OPERATION                            아래 표에 자세히 설명 되어 있습니다.

 OPTIONS                                     아래 표에 자세히 설명 되어 있습니다.

 OBJECT_NODE                          사용한 데이터베이스 링크

 OBJECT_OWNER                                해당 라인의 오브젝트를 생성한 사용자 그룹

 OBJECT_NAME                          테이블이나 인덱스, 클러스터등의 이름

 OBJECT_INSTANCE                      SQL FROM절에 기술된 오브젝트를 좌에서 우로 부여한 번호

 OBJECT_TYPE                          오브젝트의 종류( non-unique index)

 ID                                          수립된 각 실행단계에 붙여진 일련번호

 PARENT_ID                            해당 ID의 부모가 가진 ID

 POSITION                                    같은 부모 ID를 가지고 있는 자식 ID간의 처리 순서

 OTHER                                       다른 필요한 텍스트를 지정하기 위한 필트

 ------------------------------------------------------------------------------------------------

 

 

OPERATION의 종류와 OPTIONS에 대한 설명

 

OPERATION(기능)               OPTIONS(옵션)                      

---------------------------------------------------------------------------------------------------------------------------------

AGGREGATE                             GROUP BY                              그룹함수를 사용하여 하나의 로우가 추출되도록 하는 처리(버전 7에서만 표시됨)

AND-EQUAL                                                                   인덱스 머지를 이용하는 경우

CONNECT BY                                                                  CONNECT BY를 사용하여 트리 구조로 전개

CONCATENATION                                                               단위 액세스에서 추출한 로우들의 합집합을 생성

COUNTING                                                                           테이블의 로우스를 센다

FILTER                                                                             선택된 로우에 대해서 다른 집합에 대응되는 로우가 있다면 제거하는 작업

FIRST ROW                                                                          조회 로우 중에 첫번째 로우만 추출한다.

FOR UPDATE                                                                         선택된 로우에 LOCK을 지정한다. 

INDEX                                 UINQUE                                UNIQUE인덱스를 사용한다. (단 한개의 로우 추출)

                                             RANGE SCAN                            NON-UNIQUE한 인덱스를 사용한다.(한 개 이상의 로우)

                                             RANGE SCAN                            RANGE SCAN하고 동일하지만 역순으로 로우를 추출한다.

                                             DESCENDING 

INTERSECTION                                                                교집합의 로우를 추출한다.

MERGE JOIN                            OUTER                                 먼저 자신이ㅡ 조건만으로 액세스한 후 각각을 SORT하여

                                                                                           MERGE해 가는 조인

                                                                                           위와 동일한 방법이지만  outer join을 사용한다.

MINUS                                                                              MINUS 함수를 사용한다.

NESTED LOOPS                  OUTER                                 먼저 어떤 드라이빙 테이블의 로우를 액세스한 후 그 결과를

                                                                                           이용해 다른 테이블을 연결하는 조인

                                                                                           위와 동일하지만 outer join을 사용한다.

PROJECTION                                                                         내부적인 처리의 일종

REMOTE                                                                             다른 분산 데이터베이스에 있는 오브젝트를 추출하기 위해

                                                                                           DATABASE LINK를 사용하는 경우

SEQUENCE                                                                           시퀀스를 액세스 한다.

SORT                                  UNIQUE                                같은 로우를 제거하기 위한 SORT

                                             GROUP BY                              액세스 결과를 GROUP BY 하기 위한 SORT

                                             JOIN                                  MERGE JOIN을 하기 위한 SORT

                                             ORDER BY                              ORDER BY를 위한 SORT

TABLE ACCESS                  FULL                                  전체 테이블을 스캔한다.

                                             CLUSTER                               CLUSTER를 액세스 한다.

                                             HASH                                  키값에 대한 해쉬 알고리즘을 사용(버전 7에서만)

                                             BY ROWID                              ROWID를 이용하여 테이블을 추출한다.

UNION                                                                              두 집합의 합집합을 구한다.(중복없음)

                                                                                           항상 전체 범위 처리를 한다.

UNION ALL                                                                          두 집합의 합집합을 구한다.(중복가능)

                                                                                           UNION과는 다르게 부분범위 처리를 한다.

VIEW                                                                               어떤 처리에 의해 생성되는 가상의 집합에서 추출한다.(주로 서브쿼리에 의해 수행된 결과)

=======================================================================================================

출처 : http://jaehan.tistory.com/92?srchid=BR1http%3A%2F%2Fjaehan.tistory.com%2F92

EXPLAIN PLAN 이란?

 

사용자들이 SQL 문의 액세스 경로를 확인하고
튜닝을 할 수 있도록 SQL 문을 분석하고 해석하여 실행 계획을 수립한 후
실행 계획을 테이블(plan_table)에 저장하도록 해주는 명령 입니다.


1. PLAN TABLE의 생성

Explain plan을 sql 에 포함해서 수행하면 옵티마이저가 실행 계획까지만
수립하여 plan_table에 저장해 둡니다.

PLAN을 사용하고자 하는 USER로 SQLPLUS LOGIN한 후
ORACLE_HOME/RDBMS/ADMIN/utlxplan.sql을 수행하여 plan_table을 생성 합니다.


C:\>SQLPLUS scott/tiger

SQL*Plus: Release 10.2.0.1.0 - Production on 화 10월 10 16:41:26 2006

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


다음에 접속됨:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> @C:\oracle\product\10.2.0\db_2\RDBMS\ADMIN\utlxplan.sql

테이블이 생성되었습니다.

SQL>

 

2. PLUSTRACE ROLE의 생성
sqlplus "/ as sysdba"로 접속하여 PLUSTRACE ROLE을 생성 합니다.
ORACLE_HOME/sqlplus/admin/plustrce.sql을 수행하여 plustrace role을 생성 합니다.

 

C:\>sqlplus "/ as sysdba"

SQL*Plus: Release 10.2.0.1.0 - Production on 화 10월 10 17:01:26 2006

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


다음에 접속됨:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> @C:\oracle\product\10.2.0\db_2\sqlplus\admin\plustrce.sql
SQL>
SQL> drop role plustrace;
drop role plustrace
          *
1행에 오류:
ORA-01919: 롤 'PLUSTRACE'(이)가 존재하지 않습니다


SQL> create role plustrace;

롤이 생성되었습니다.

SQL>
SQL> grant select on v_$sesstat to plustrace;

권한이 부여되었습니다.

SQL> grant select on v_$statname to plustrace;

권한이 부여되었습니다.

SQL> grant select on v_$mystat to plustrace;

권한이 부여되었습니다.

SQL> grant plustrace to dba with admin option;

권한이 부여되었습니다.

SQL>
SQL> set echo off
SQL>

 

3. PLUSTRACE Role의 부여

PLUSTRACE ROLE을 plan을 사용하고자 하는 유저에게 부여 합니다.

 

SQL> GRANT plustrace TO scott;

권한이 부여되었습니다.


권한을 부여 한다음.
다시 plan을 사용하는 유저로 접속을 합니다.

SQL> conn scott/tiger
연결되었습니다
.


autotrace 상태를 on으로 바꿉니다.

SQL> SET AUTOTRACE ON  ;
SQL>


SQL문을 실행 합니다.

SQL> SELECT a.ename, a.sal, b.dname
  2   FROM emp a, dept b
  3  WHERE a.deptno = b.deptno;

 

ENAME             SAL DNAME
---------- ---------- --------------
SMITH             800 RESEARCH
ALLEN            1600 SALES
WARD             1250 SALES
JONES            2975 RESEARCH
MARTIN           1250 SALES
BLAKE            2850 SALES
CLARK            2450 ACCOUNTING
SCOTT            3000 RESEARCH
KING             5000 ACCOUNTING
TURNER           1500 SALES
ADAMS            1100 RESEARCH

ENAME             SAL DNAME
---------- ---------- --------------
JAMES             950 SALES
FORD             3000 RESEARCH
MILLER           1300 ACCOUNTING

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


Execution Plan
----------------------------------------------------------
Plan hash value: 351108634

--------------------------------------------------------------------------

| Id  | Operation                                        | Name    | Rows  | Bytes | Cost (%CPU)| Time      |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT                       |               |     14 |    364 |        4       (0)| 00:00:01 |

|   1 |  NESTED LOOPS                             |               |     14 |    364 |        4       (0)| 00:00:01 |

|   2 |   TABLE ACCESS FULL                    | EMP        |     14 |    182 |        3       (0)| 00:00:01 |

|   3 |   TABLE ACCESS BY INDEX ROWID| DEPT       |       1 |     13 |        1       (0)| 00:00:01 |

|*  4 |    INDEX UNIQUE SCAN                 | PK_DEPT  |       1 |          |        0       (0)| 00:00:01 |

--------------------------------------------------------------------------


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

   4 - access("A"."DEPTNO"="B"."DEPTNO")


Statistics
----------------------------------------------------------
        626  recursive calls
          0  db block gets
        134  consistent gets
         10  physical reads
          0  redo size
        856  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
         10  sorts (memory)
          0  sorts (disk)
         14  rows processed

SQL>


⊙ 참고


☞ 8.17
@C:\oracle\ora81\RDBMS\ADMIN\utlxplan.sql; 
@C:\oracle\ora81\sqlplus\admin\plustrce.sql;

 

☞ 10g
@C:\oracle\product\10.2.0\db_2\RDBMS\ADMIN\utlxplan.sql
@C:\oracle\product\10.2.0\db_2\sqlplus\admin\plustrce.sql

 

⊙ Golden(골든)의 결과

 - Ctrl + P 키를 누루면 결과 나온다.

 
TOAD(토드)에서 설정방법
- Ctrl + E 키를 누루면 결과 나온다.
 
PLAN 테이블(TOAD_PLAN_TABLE)이 존재한다면 
TOAD 상단 메뉴에서
View 메뉴 > Options 메뉴 내용중 "Oracle > General" 에 Explain Plan Table Name 이 있습니다. 이곳에 "TOAD_PLAN_TABLE" 이라 명시하시고 사용하면 됩니다

반응형

'ORACLE > TUNING' 카테고리의 다른 글

Oracle Hidden Parameter 란  (0) 2010.01.26
FAST_START_MTTR_TARGET  (0) 2010.01.18
Statspack Report 간단 분석 방법  (0) 2009.12.17
cursor_sharing 파라미터에 대한 테스트  (0) 2009.12.16
Literal SQL 조회하는 방법  (0) 2009.12.05
Posted by [PineTree]
ORACLE/ORACLE TOOL2009. 3. 27. 09:21
반응형
출처 : http://blog.daum.net/maihikki/9078992

방 1)

Sql Plus 에서 아래 코드 붙여넣기 하신후 실행하시고

@C:\oracle\ora92\rdbms\admin\utlxplan.sql

toad-view-option-oracle-general 에서 가운데쯤 보시면 Explan Plan Table Name이라는 항목이 있습니다. 거기에 Plan_Table 이라고 기재하신후 사용하면 됩니다.

 

 

방 2)

토드에서 explain plan을 볼려면 아래의 스크립트를 실행 시킵니다.
C:\Program Files\Quest Software\TOAD\temps\toadprep.sql

 

toadprep.sql을 열어보면 toad유저를 생성할 때..
테이블스페이스를 지정하는데 데이타베이스에 존재하는 테이블 스페이스에 맞게 수정해야 합니다.

 

=============== 아래 부분은 제 오라클에 맞게 수정한 부분입니다. ===================

CREATE USER TOAD IDENTIFIED BY TOAD
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP
QUOTA UNLIMITED ON USERS
QUOTA 0K ON SYSTEM;

============================================================================

 

toadprep.sql스크립트가 에러없이 수행이 되면 오라클에 toad라는 유저가 생성되고...

toad_plan_table, toad_plan_sql 테이블이 생성이 됩니다.

또한 시퀀스, 시노님, 권한부여, 함수가 에러없이 생성이 되면 설치가 다 끝난겁니다.


 

실행계획을 보는 방법은 우선 SQL을 실행할 유저로 토드를 접속합니다..

 

그리고 나서 sql 을 실행하고 나면 토드 아래에  explain plan과 autotrace를 보면 됩니다.

 

아래의 그림은 제 피시에서 실행한 예 입니다..아래의 explain plan이 보이지 ?을 경우에는 토드 메뉴에서 view->explain plan을 선택하거나 아래 그림 맨 오른쪽 세번째 있는 엠브런스차 아이콘을 클릭하면 됩니다..

 

실행 계획을 보는 방법은 Operation 컬럼에 나온 내용과 아래의 표를 참고해서  보시면 됩니다.

그리고 Explain Plan 오른쪽에   Auto Trace를 보면 Trace정보가 나옵니다..

 

AutoTrace관련 몇 가지를 설명하면 아래와 같습니다.

  • db block gets : current gets에 대한 논리적인 IO횟수(in memory)
  • consistent gets : read-consistent gets에 대한 논리적인 IO횟수(in memory)
  • physical reads : Disk에서 읽은 블럭수
  • redo size : (DML)문에 의해 생성된 redo의 양
  • sorts(memory) : memory에서 수행된 sort횟수
  • sorts(disk) : Temporary 영역에서 sort된 횟수

     

    이미 아시겠지만 db block gets와 consistent gets는 Logical Read를 나타냅니다.
    두개를 더한 값과 Pysical Reads를 비교해서 Hit Ratio를 구하죠.

    우선 consistent gets는 consistent mode에서 db block read를 수행한 숫자입니다.

    TKPROF 레포트에서 query에 해당하는 값입니다.

     

    consistent라는 말은 read consistency와 관련이 있는데 즉 읽기 일관성이 보장되는 상황에서 읽는 숫자라는 것입니다. 데이터를 수정하지 않고 단지 읽기만 하기때문에 lock이 발생하지 않습니다.

    db block gets는 CURRENT mode에 있는 block의 데이터를 읽은 숫자입니다. TKPROF 레포트에서 current에 해당하는 값이구요. current mode에서는 곧 수정될 Segment header나 block을 얻을 때 일어납니다. INSERT, UPDATE, DELETE에서 데이터 쿼리부분이 아니라 수정될 값을 읽을 때 나타나는 숫자입니다. select문일 경우에는 Full table scan일 경우 Segment header를 읽을 때 나타납니다.

    위의 내용은 Performance Tuning 문서에 있는 내용을 대충 정리한 것입니다. 그래서 아마도 위의 내용은 대부분 보셧을 내용이겠지만, 정확한 차이점을 이해하려면 더 많은 것들을 알고 이해해야합니다.

    여기서 Consistent mode와 current mode가 무엇인지를 아는 것이 중요합니다.

    우선 Consistency를 알기 위해서 오라클이 제공하는 Mulitversion concurrency control에 대해 알아야 합니다. 사용자가 쿼리를 날렸을때 그 순간의 이미지를 가지고 데이터를 가져오게 됩니다. 쿼리를 날린 후에 다른 세션에서(자기 자신의 세션에서도 마찬기지입니다.) 원하는 데이터가 수정이 되어도 처음 쿼리의 처리를 시작한 순간의 내용을 오라클은 제공합니다. 이런 처리를 위해 쿼리가 실행되는 순간 SCN(System change number)가 결정의 되고 각 DB Block의 scn과 비교하여 더 큰 scn을 가지고 있는 경우 즉 변경이 일어난 경우에는 rollback segment에서 과거의(자신의 scn보다 낮은 scn을 가지고 있는) 이미지의 block을 가지고 오게 됩니다.

    consistent gets가 consistent mode에서 block의 데이터를 읽은 숫자라는 것은 이와 같이 읽기 일관성이 보장되는 상황에서 읽은 block의 숫자라는 것입니다.

    DML문장이 수행되는 경우에 처리되는 부분을 두 부분으로 나눌 수 있는데, 하나는 수정할 데이터를 찾기 위해 읽는 부분이고, 다른 하나는 실제 데이터를 수정하기 위해 데이터를 읽는 부분입니다. 데이터를 찾기위해 읽는 부분은 INSERT문의 sub query부분과 delete문과 update문의 where 조건절에 해당하는 부분이나 sub query에 해당하는 부분입니다.

    DML문에서는 데이터를 찾기 위한 부분이 consistent gets에 나타나고 수정하기 위한 부분이 db block gets에 나타납니다.

    update t set value = value 5 where value > 10;
    예를 들어 위와 같은 문장을 보면 처음 위의 문장이 실행 되는 순간의 이미지를 이용해서 조건에 맞는 즉 value가 10보다 큰 row들을 찾습니다. 그리고 각각의 row를 실제로 update하는 value = value 5를 실행할때는 current mode에서 수행이 됩니다. 조건에 해당하는 row를 이미 읽었지만 수정하기 위해서 다시 또 읽게 됩니다. 이 때는 실제 데이터를 수정해야 하기 때문에 지금 바로 현재의 데이터여야 합니다. consistent mode에서 읽은 데이터는 과거의 이미지의 데이터일 수 있지만 수정시에는 가장 최근의 버젼을 수정해야 하기 때문입니다. 즉 current mode라는 것은 과거의 시점이 아닌 바로 지금의 data를 읽는 것을 말합니다.

    update문을 수행시에 consistent gets와 db block gets의 숫자를 비교해 보면 db block gets의 숫자가 더 큰 경우를 보게 되는데 이것은 consistent gets는 즉 수정될 로우를 찾을 경우는 block단위로 io가 일어나서 읽은 block의 수를 나타내게 되지만, db block gets는 즉 수정될 로우를 찾을 때는 각 로우마다 current mode에서 데이터를 읽기 때문에 같은 block도 row의 수만큼 읽게 됩니다. trace를 보시면 db block gets의 수는 실제 수정될 row의 수와 거의 같은 것을 확인하실 수 있습니다.

    consistent gets는 physical reads를 포함하고 있기 때문에 실제로 쿼리를 튜닝할 때 중요한 것은 Logical IO를 줄이는 것입니다. 이것에 관한 내용도 설명하자면 매우 길어지므로 여기서는 logical reads의 한 경우인 db block gets의 관한 예를 하나만 들겠습니다.

    다음의 두 문장은 똑 같은 읽을 수행합니다. 읽은 범위는 똑 같습니다. 즉 consistent reads의 수는 동일합니다. 그러나 db block gets의 숫자는 두배의 차이가 있기때문에 속도의 차이가 있습니다. 직접 샘플을 만들어 확인해 보시기 바랍니다.

    UPDATE ta A
    SET A.QTY = (
    SELECT SUM(B.QTY) A.QTY
    FROM tb B
    WHERE B.ID = A.ID
    );

    UPDATE ta A
    SET A.QTY = A.QTY (
    SELECT SUM(B.QTY)
    FROM tb B
    WHERE B.ID = A.ID
    );


    질문의 내용에는 벗어나지만 성능을 향상시키기 위해서는 LIO를 줄여야합니다. 모든 LIO는 latch를 발생시키기 때문에 가능한 적은 LIO를 수행하도록 하여야 좋은 성능과 확장성을 보장할 수 있습니다.

  • 반응형
    Posted by [PineTree]