Post

[Oracle 튜닝] SQL 실행계획 분석

[Oracle 튜닝] SQL 실행계획 분석

Oracle Autonomous Database(ADB) 환경에서 실습 스키마 구성 후, 기본 SQL 튜닝 실습 수행


✅ 실습 환경

  • Oracle ADB (Autonomous Transaction Processing)
  • SQL Developer
  • 실습 계정: SCOTT
  • 기본 테이블: EMP, DEPT

✅ 실습 스키마(SCOTT)

1
2
3
4
5
6
7
8
9
-- 1. 사용자 생성 (기본 테이블스페이스: DATA)
CREATE USER SCOTT IDENTIFIED BY [PASSWORD]
DEFAULT TABLESPACE DATA
TEMPORARY TABLESPACE TEMP
QUOTA UNLIMITED ON DATA;

-- 2. 권한 부여
GRANT CONNECT, RESOURCE TO SCOTT;
GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW, CREATE SEQUENCE, CREATE PROCEDURE TO SCOTT;

✅ 실행계획 확인

1
2
3
4
5
6
7
8
/* 1. 실행계획 저장 */
EXPLAIN PLAN FOR
SELECT E.ENAME, E.JOB, D.DNAME, E.SAL
FROM EMP E
JOIN DEPT D ON E.DEPTNO = D.DEPTNO;

/* 2. 저장된 실행계획 조회 */
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Plan hash value: 3321496967
 
---------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |    13 |   442 |     4   (0)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR       |          |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM) | :TQ10000 |    13 |   442 |     4   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|*  3 |    HASH JOIN          |          |    13 |   442 |     4   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|   4 |     TABLE ACCESS FULL | DEPT     |     4 |    52 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|   5 |     PX BLOCK ITERATOR |          |    13 |   273 |     2   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|   6 |      TABLE ACCESS FULL| EMP      |    13 |   273 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
---------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   3 - access("E"."DEPTNO"="D"."DEPTNO")
 
Note
-----
   - automatic DOP: Computed Degree of Parallelism is 4

✅ 1. 기본 JOIN 실행계획

1
2
3
SELECT E.ENAME, E.JOB, D.DNAME, E.SAL
FROM EMP E
JOIN DEPT D ON E.DEPTNO = D.DEPTNO;
  • HASH JOIN 사용됨
  • EMP, DEPT 모두 TABLE ACCESS FULL
  • 병렬 처리(PX COORDINATOR) 자동 활성화됨
  • DEPT.DEPTNO는 PK라 인덱스 있음에도 풀스캔된 이유: → 데이터 소량 + PX 병렬 처리의 영향

✅ 2. COUNT(*) vs COUNT(컬럼)

1
SELECT COUNT(*) FROM DEPT;
  • INDEX FULL SCAN (PK_DEPT) 사용됨
1
SELECT COUNT(DNAME) FROM DEPT;
  • TABLE ACCESS FULL 발생
  • 이유: DNAME은 NULL 여부 체크 필요 → 인덱스 없음

✅ 3. 힌트 사용

1
SELECT /*+ FULL(DEPT) */ COUNT(*) FROM DEPT;
  • 인덱스 우선 선택을 강제로 테이블 풀스캔으로 유도
  • 실행계획 결과: TABLE ACCESS FULL

✅ 4. ADB의 PX 처리 영향

  • PX 관련 연산자 (PX COORDINATOR, PX SEND, PX BLOCK) 항상 포함됨
  • 옵티마이저가 병렬 처리 기준으로 실행계획을 잡기 때문에 로컬 Oracle과 다른 PLAN 구조가 나올 수 있음

힌트 (FULL, INDEX, NO_PARALLEL 등)는 잘 적용됨


✅ 정리

쿼리액세스 방식힌트특징
COUNT(*)INDEX FULL SCAN인덱스만으로 처리 가능
COUNT(DNAME)TABLE ACCESS FULL컬럼 null 확인 필요
COUNT(*) + FULL(DEPT)TABLE ACCESS FULL힌트로 인덱스 무시
JOIN EMP-DEPTHASH JOINPX 자동소량 데이터라도 PX 실행됨
This post is licensed under CC BY 4.0 by the author.