#oracle #sql-tunning

Chapter 3. 실행계획 | Chapter 4. 실행계획 종류

Dec 7, 2022


실행 계획 (Execution Plans)

EXPLAIN PLAN FOR

아래와 같이 SQL 구문 앞에 EXPLAIN PLAN FOR 명령을 추가하게 되면 SQL문의 예상 실행계획을 생성하고 이 실행계획을
PLAN_TABLE에 INSERT하게 된다.

EXPLAIN PLAN FOR
 SELECT * FROM emp
 WHERE job = 'CLERK' ; 

이렇게 생성, 저장된 실행 계획을 확인하려면 아래 명령을 수행하면 된다.

SELECT * FROM table(dbms_xplan.display) ;

예상 실행 계획 확인 : dbms_xplan.display()

파라미터를 사용하지 않을 경우 PLAN_TABLE을 대상으로 하며, 마지막 생성된 실행 계획을 TYPICAL 포멧으로 불러온다.
아래와 같이 파라미터를 지정할 경우 지정된 실행계획을 출력한다.

SELECT * FROM table(dbms_xplan.display({실행 계획 테이블}, {PLAN_TABLE.STATEMENT_ID}, {실행 계획 포멧})); 

예상 실행 계획 <-> 실제 실행 계획

옵티마이저가 예상한 실행계획은 표본을 통해 도출한 실행 계획이며 전체를 대상으로 도출한 예상 실행 계획이라도
당시 실행계획을 도출한 상황과 현재 데이터는 크게 달라져있을 수 있으므로 실제 실행 계획과 동일시 하면 안된다.

그러므로 쿼리 튜닝과 튜닝 포인트 확인을 위해서는 실제 실행 쿼리의 실행 계획을 확인하는 것이 선행되어야 한다.


실제 실행 계획 확인 : dbms_xplan.display_cursor()

아래 패키지 함수를 사용하여 가장 최근 실행된 쿼리의 실행 계획을 확인할 수 있다.

// 파라미터를 사용하지 않으면 실제로 수행된 마지막 쿼리의  번째 CURSOR_CHILD_NO 값으로 실행계획을 `TYPICAL` 포멧을 통해 가져온다.
SELECT * FROM table(dbms_xplan.display_cursor) ;

파라미터를 통해 SQL_ID, CURSOR_CHILD_NO, 실행 계획 출력 FORMAT을 지정하여 실행 계획을 확인할 수 있다.

SELECT * FROM table(dbms_xplan.display_cursor({SQL_ID}, {CURSOR_CHILD_NO}, {실행 계획 출력 FORMAT})) ;

실행 통계 확인

DBMS_XPLAN.DISPLAY_CURSOR의 출력 결과는 실제 사용된 실행 계획을 보여 주긴 하나,
그 이외의 칼럼들(Rows, Bytes, Cost, Time)의 값 등은 모두 Parse 단계에서 생성된 예상 값을 보여준다.
실제 문장의 실행 도중 사용된 자원의 사용량을 확인하기 위해서는 IOSTATS, MEMSTATS 등의 추가적인 출력 포맷을 사용한다.

// 사용 가능한 추가적 포맷
IOSTATS   I/O 사용 횟수
MEMSTATS  메모리 사용량
ALLSTATS  모든 통계 포함

하지만 모든 실행 쿼리를 대상으로 통계를 수집할 경우 서버 프로세스의 부하가 크게 가중되므로
이를 수집하기 위해서는 아래와 같은 추가 설정이 필요하다.

1. 문장 레벨의 실행 통계 수집(힌트 사용)
SELECT /*+ gather_plan_statistics */ * FROM dept
 WHERE deptno = 10;
2. 세션 레벨의 실행 통계 수집
ALTER SESSION SET statistics_level = ALL ;
3. 시스템 레벨의 실행 통계 수집

시스템 레벨의 통계 수집은 관련 모든 쿼리를 수집하므로 사용하지 않는 것을 추천

ALTER SYSTEM SET statistics_level = ALL ; 
[ALLSTAT 실행 통계 예시]
SQL_ID  9navctnqnq3qx, child number 0
-------------------------------------
select  /*+ gather_plan_statistics */ channel_id, count(*)  from sales  
where channel_id = 9  group by channel_id
 
Plan hash value: 541818681
 
---------------------------------------------------------------------------------------------------
| Id  | Operation            | Name             | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                  |      1 |        |      1 |00:00:00.01 |       7 |
|   1 |  SORT GROUP BY NOSORT|                  |      1 |    229K|      1 |00:00:00.01 |       7 |
|*  2 |   INDEX RANGE SCAN   | SALES_CHANNEL_IX |      1 |    229K|   2074 |00:00:00.01 |       7 |
---------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("CHANNEL_ID"=9)


SQL Trace


SQL Monitoring (11g New Features)

문장 단위 SQL Monitoring

SELECT /*+ monitor */ * FROM emp WHERE deptno = 10 ;



*****

© 2021, Ritij Jain | Pudhina Fresh theme for Jekyll.