티스토리 툴바

365차원


DISPLAY , DISPLAY_CURSOR , DISPLAY_AWR 함수가 많이 쓰이는 DBMS_XPALN

DBMS_XPLAN 패키지는 아래와 같은 함수를 제공합니다.

1. DISPLAY   (9i  ↑)
    table_name  :default 'PLAN_TABLE'
    statement_id :default NULL
    format  :default 'TYPICAL'
    filter_preds :default NULL

:예상 실행 계획 

2. DISPLAY_CURSOR  (10G ↑)
    sql_id   :default null
    child_number :default null
    fromat       :default 'TYPICAL'

:실제 실행계획

3. DISPLAY_AWR   (10G ↑)
    sql_id 
    plan_hash_value :default null
    db_id     :default null
    format          :default 'TYPICAL'

:AWR 을 통해 얻은 항목별 TOP SQL 의 실행계획

4. DISPLAY_SQLSET  (10G ↑)
    sqlset_name    
    sql_id
    plan_hash_value :default null
    format          :default 'TYPICAL'
    sqlset_owner    :default null


:SQL TUNING ADVISOR 을 통해 얻은 튜닝 실행계획
          

11G에서는 다음과 같은 함수가 추가 되었습니다.

5. DISPLAY_SQL_PLAN_BASELINE  (11G ↑)

:SQL PLAN BASELINE 를 통한 후보 실행계획

 

 


--DISPLAY

DBMS_XPLAIN.DISPLAY 함수는
EXPLAIN PLAN FOR SELECT.... 로 분석된 예상 실행계획을 조회 할수 있습니다.
SET AUTOTRACE 와 같은 기능을 수행한다고 생각해도 무방합니다.

EX) SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)

기본적으로는 마지막에 실행 분석된 SQL 문에 대한 예상 실행계획을 조회 하지만

STATEMENT_ID 를 지정해 기록되어 있는 실행계획을 확인 하는것또한 가능합니다.


-분석
EXPLAIN PLAN
SET STATEMENT_ID = 'A1'   -- STATEMENT_ID 를  지정합니다.
FOR SELECT  * FROM EMP;

-조회
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE','A1','TYPICAL'));           
-------------------{DBMS_XPLAN.DISPLAY('plan table','statement_id'가장마지막 일경우 null , 'option' )}

 

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------
Plan hash value: 3956160932
-------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    10M|   171M|  7639   (6)| 00:01:32 |
|   1 |  TABLE ACCESS FULL| EMP  |    10M|   171M|  7639   (6)| 00:01:32 |
--------------------------------------------------------------------------

(실행계획을 한줄에 담기는 어렵네요...)


동일한 STATEMENT_ID 를 지정할 경우 마지막에 지정된 분석 결과를 가지고 있으므로 이점 유의 하시길 바랍니다.


DBMS_XPLAN 의 장점중 하나는 보고자 하는 포멧 를 컨트롤 할수 있다는 점이다.

all :
     plan 정보는 typical 과 같으나 plan 이외의 정보중에서
     outline data 정보를 제외하고 모두 출력한다.


advanced : 
     all 에서 보여주는 정보와 peeked binds , outline data , note
     를 추가로 보여준다


allstats : 
      operation 별로 query block name 과  object alias 를 control 한다.


last :
       가장 마지막에 수행된 수행된 실행통계를 출력하며 명시 하지 않을시
       누적된 실행 통계를 출력한다.


이외에도 몇가지  컨트롤 명령어가 더 존재합니다.
 

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE',NULL,'ALL'))

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------
Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    10M|   171M|  7639   (6)| 00:01:32 |
|   1 |  TABLE ACCESS FULL| EMP  |    10M|   171M|  7639   (6)| 00:01:32 |
--------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / EMP@SEL$1

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - "EMP"."EMPNO"[NUMBER,22], "EMP"."JOB"[VARCHAR2,2],
       "EMP"."HIREDATE"[DATE,7], "EMP"."DEPTNO"[NUMBER,22]

이런식으로 표시됩니다~
 

  

--DISPLAY_CURSOR

 

DISPLAY 함수가 예상 실행계획 을 조회 했었다면..


DBMS_XPLAIN.DISPLAY_CURSOR 함수는
SHARED POOL 의 실제 실행 계획을 조회 할수 있습니다.

이를 위해 1회 의 실제 SQL문을 실행 하여야 하지만
SHARED POOL 에 남아 있는 한
다시 SQL문을 실행하지 않아도 계속 적인 조회가 가능합니다.


SELECT * FROM EMP WHERE DEPTNO = '10';

과 같이 실제 조회를 실행한후.


SELECT * FROM TABLE(DBMS_XPLAN.display_cursor(null,null,'typical'));

DISPLAY 함수 처럼 마지막 실행된 쿼리의 실행계획을 조회하게되면.

 

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID  9s6dwucfkaq75, child number 0
-------------------------------------
SELECT * FROM EMP WHERE DEPTNO = '10'

Plan hash value: 3324114979

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |       |       |     4 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    18 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | EMP_N1 |     1 |       |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

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

   2 - access("DEPTNO"=10)

이와 같이 실제 수행된 실행계획과


SQL_ID ,
child number,
number plan hash value 와 함게 실제 수행된 실행 계획을 얻을수있습니다.


사용방법은 DBMS_XPLAN.display_cursor(sql_id,child number,'typical')

아래 예문에 따라 아래와 같이 재조회가 가능합니다.

SELECT * FROM TABLE(DBMS_XPLAN.display_cursor('9s6dwucfkaq75','0','typical'));

DBMS_XPLAN.display_cursor 함수는

/*+ gather_plan_statistics */ 힌트와 함계 사용 할경우

실제와 예측된 실행계획 등 아주 상세한 정보를 제공 하여 줍니다.


SELECT /*+ gather_plan_statistics */ *
FROM EMP WHERE DEPTNO = '10'

SELECt * FROM TABLE(DBMS_XPLAN.display_cursor(null,null,'advanced allstats last'));

 

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  aa1xcwc6jg8w1, child number 0
-------------------------------------
SELECT /*+ gather_plan_statistics */ * FROM EMP WHERE DEPTNO = '10'

Plan hash value: 1182541070

---------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |
---------------------------------------------------------------------------------------------------------------------------------------------
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP        |      1 |      1 |    18 |     4   (0)| 00:00:01 |      9 |00:00:00.04 |       6 |      4 |
|*  2 |   INDEX RANGE SCAN          | EMP_DEPTNO |      1 |      1 |       |     3   (0)| 00:00:01 |      9 |00:00:00.03 |       4 |      3 |
---------------------------------------------------------------------------------------------------------------------------------------------(보기어렵네요 ㄱ-)

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / EMP@SEL$1
   2 - SEL$1 / EMP@SEL$1

Outline Data
-------------

  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
      OPT_PARAM('_optimizer_cost_model' 'cpu')
      OPT_PARAM('_optim_peek_user_binds' 'false')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX(@"SEL$1" "EMP"@"SEL$1" ("EMP"."DEPTNO"))
      END_OUTLINE_DATA
  */

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

   2 - access("DEPTNO"=10)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - "EMP"."EMPNO"[NUMBER,22], "EMP"."JOB"[VARCHAR2,2], "EMP"."HIREDATE"[DATE,7], "DEPTNO"[NUMBER,22]
   2 - "EMP".ROWID[ROWID,10], "DEPTNO"[NUMBER,22]

 

위와 같이 contorl 옵션 별로 자세한 정보들을 얻을수있습니다.

(위는 advanced allstats last 3가지의 옵션을 통해 얻은 정보입니다만 어떠한 옵션을 선택하느냐에 따라
출력 항목 들이 달라지게 됩니다.)

 


오라클이 SQL text 를 여러개의 query block 로 나누어 관리하는대

oracle 에서 부여하는 internel Query Block Name  를 

QB_name 흰트 등을 사용해 이용자가 명시적으로  부여 하여

복잡한 쿼리의 를 쉽게 파악하여 컨트롤 할수있습니다..

 

Query Block Name 사용한 실행계획 변경

EXPLAIN PLAN FOR
SELECT /*+ QB_NAME(yep) */ *
FROM EMP WHERE DEPTNO = '10'

위와 같이 QB_NAME 힌트를 사용하여 조회 하게 될경우 아래와 같은 실행 겨획을 볼수 있습니다.


------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |     1 |    18 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP        |     1 |    18 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | EMP_DEPTNO |     1 |       |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - YEP / EMP@YEP
   2 - YEP / EMP@YEP

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

   2 - access("DEPTNO"=10)

 

QB_NAME HINT 를 사용하지 않는다면


------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |     1 |    18 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP        |     1 |    18 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | EMP_DEPTNO |     1 |       |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / EMP@SEL$1
   2 - SEL$1 / EMP@SEL$1


이와같은 interner 한 block name 를 나타내게됩니다. 위와 아래의 YEP와 SEL$1 차이 보이시죠?

query block name 을  명시적으로 지정함으로써

좀더 복잡한 문장의 쿼리들(여러개의 query block 을 이용하는 SQL) 들이

실행계획의 어떤부분에 속하는지 파악하기도 쉬워지게됩니다.

이제 QB_NAME 를 사용해 실행계획을 변경 하여 보겠습니다.


 EXPLAIN PLAN FOR
 SELECT t1.* from (
 SELECT T.*
 FROM EMP T WHERE DEPTNO = '10') T1 ,dept t2
 where t1.deptno = t2.deptno

-------------------------------------------------------------------------------------------
| Id  | Operation                    | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |            |     1 |    21 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |            |     1 |    21 |     3   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN          | DEPT_U1    |     1 |     3 |     0   (0)| 00:00:01 |
|   3 |   TABLE ACCESS BY INDEX ROWID| EMP        |     1 |    18 |     3   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN          | EMP_DEPTNO |     1 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$F5BB74E1
   2 - SEL$F5BB74E1 / T2@SEL$1
   3 - SEL$F5BB74E1 / T@SEL$2
   4 - SEL$F5BB74E1 / T@SEL$2

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

   2 - access("T2"."DEPTNO"=10)
   4 - access("DEPTNO"=10)


이와같 실행 계획을 보이는 SQL문을


EXPLAIN PLAN FOR
SELECT /*+  FULL(@YEP T ) */ t1.* from (
SELECT /*+ QB_NAME(yep) */ T.*
FROM EMP T WHERE DEPTNO = '10') T1 ,dept t2
where t1.deptno = t2.deptno

------------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |     1 |    21 |  7725   (7)| 00:01:33 |
|   1 |  NESTED LOOPS      |         |     1 |    21 |  7725   (7)| 00:01:33 |
|*  2 |   INDEX UNIQUE SCAN| DEPT_U1 |     1 |     3 |     0   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| EMP     |     1 |    18 |  7725   (7)| 00:01:33 |
------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$453F6D3F
   2 - SEL$453F6D3F / T2@SEL$1
   3 - SEL$453F6D3F / T@YEP

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

   2 - access("T2"."DEPTNO"=10)
   3 - filter("DEPTNO"=10)

(QB_NAME를 이용하여 실행 계획을 변경시키는 예제가 목적이므로 성능은 PASS)

 

3.DISPLAY_AWR 함수를 이용해  AWR 에서 보관중인 TOP SQL 에 대한 정보를 조회 할수있습니다.

Elapsed time(ms)
cpu time(ms)
executions
buffer gets
disk reads
parse calls
rows
user i/o wait time (ms)
cluster wait time (ms)
appllcation wait time (ms)
concurrency wait time (ms)
invalidations
version count
charable mem(KB)

위와 같은 항목으로 각각 30개 의 SQL 을 보관합니다.

11G 에서는  colored sql 로 SQL의 정보만 수집할수 있는
기능이 추가 되었습니다

 

4.DISPLAY_SQLSET 함수를 통해  SQL TUNING ADVISOR 를 통해 분석한 튜닝 실행 계획을 조회 할수있습니다.
5.DISPLAY_SQL_PLAN_BASELINE 함수는(11G) 에서 부터 사용되며 후보 실행계획들 조회 할수 있습니다.

 

 

 


 

저작자 표시 비영리 변경 금지
Posted by 농약마신소년
ORACLE 를 괴롭혀보다./TUN l 2009/05/20 12:40
TISTORY  공간 마련 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
자축.  글올리기 테스트
Posted by 농약마신소년
분류없음 l 2009/01/09 13:24
1 

카테고리

분류 전체보기 (2)
ORACLE 를 괴롭혀보다. (1)
정신줄을 놓다 (0)
갈굼을 받다. (0)
먹고살기 힘들다. (0)

달력

«   2012/01   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
tistory!get rss Tistory Tistory 가입하기!

공지 사항

최근에 받은 트랙백