Post

친절한 SQL 튜닝 - 8.4 DBMS_XPLAN 패키지

친절한 SQL 튜닝 - 8.4 DBMS_XPLAN 패키지

실습개요

  • 예상 실행계획과 실제 실행계획 비교
  • 실제 실행계획 확인방법
  • 실제 실행계획 분석

친절한 SQL 튜닝

8 SQL 분석 도구 4 DBMS_XPLAN 패키지 친절한 SQL 튜닝

0. 실습 준비

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
32
33
34
-- 1. 대용량 테이블 생성
CREATE TABLE EMP_BIG (
    EMPNO   NUMBER(10),
    ENAME   VARCHAR2(20),
    JOB     VARCHAR2(10),
    DEPTNO  NUMBER(5)
);

-- 2. 대량 데이터 삽입 (10만건)
INSERT INTO EMP_BIG (EMPNO, ENAME, JOB, DEPTNO)
SELECT 
    ROWNUM,
    'EMP' || ROWNUM,
    CASE MOD(ROWNUM, 3) 
        WHEN 0 THEN 'CLERK'
        WHEN 1 THEN 'MANAGER'
        ELSE 'ANALYST'
    END,
    CASE MOD(ROWNUM, 3)
        WHEN 0 THEN 20
        WHEN 1 THEN 30
        ELSE 20
    END
FROM DUAL
CONNECT BY LEVEL <= 100000;

-- 3. 인덱스 생성
CREATE INDEX EMP_BIG_X01 ON EMP_BIG(DEPTNO, JOB, EMPNO);

-- 4. ADMIN 계정으로 접속 후, 실습 계정(SQLP)에 권한 부여
GRANT SELECT ON V$SQL_PLAN_STATISTICS_ALL TO SQLP;
GRANT SELECT ON V$SQL TO SQLP;
GRANT SELECT ON V$SESSION TO SQLP;
GRANT SELECT ON V$PARAMETER TO SQLP;

1. 예상 실행계획

실제 수행 결과가 아닌 예상 값

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
-- 1. 실행계획 수집
EXPLAIN PLAN FOR
SELECT /*+ INDEX(E EMP_BIG_X01) */ *
FROM EMP_BIG E
WHERE DEPTNO = 20
  AND JOB = 'CLERK'
ORDER BY EMPNO;

-- 2. 실행계획 확인
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

PLAN_TABLE_OUTPUT                                                                          |
-------------------------------------------------------------------------------------------+
Plan hash value: 2894996259                                                                |
                                                                                           |
-------------------------------------------------------------------------------------------|
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     ||
-------------------------------------------------------------------------------------------|
|   0 | SELECT STATEMENT            |             | 22222 |   520K|   364   (0)| 00:00:01 ||
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP_BIG     | 22222 |   520K|   364   (0)| 00:00:01 ||
|*  2 |   INDEX RANGE SCAN          | EMP_BIG_X01 | 22222 |       |    89   (0)| 00:00:01 ||
-------------------------------------------------------------------------------------------|
                                                                                           |
Predicate Information (identified by operation id):                                        |
---------------------------------------------------                                        |
                                                                                           |
   2 - access("DEPTNO"=20 AND "JOB"='CLERK')                                               |

2. 실제 실행계획

예상 값과 실제 수행 결과 데이터 확인 가능

  • E-Rows: 예상 행 수
  • A-Rows: 실제 행 수
  • A-Time: 실제 수행 시간
  • Buffers: 읽은 블록 수(논리적I/O)
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
32
33
34
35
36
37
38
39
40
41
42
-- 1. 실행계획 수집
SELECT /*+ INDEX(E EMP_BIG_X01) GATHER_PLAN_STATISTICS */ *
FROM EMP_BIG E
WHERE DEPTNO = 20
  AND JOB = 'CLERK'
ORDER BY EMPNO;

-- 2. 실행계획 수집된 SQL_ID 조회
SELECT SQL_ID
FROM V$SQL 
WHERE SQL_TEXT LIKE 'SELECT /*+ INDEX(E EMP_BIG_X01) GATHER_PLAN_STATISTICS */%'
AND SQL_TEXT NOT LIKE '%V$SQL%'

SQL_ID       |
-------------+
bmxnx98v0j9ar|

-- 3. 실행계획 확인
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('bmxnx98v0j9ar',NULL,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT                                                                                    |
-----------------------------------------------------------------------------------------------------+
SQL_ID  bmxnx98v0j9ar, child number 0                                                                |
-------------------------------------                                                                |
SELECT /*+ INDEX(E EMP_BIG_X01) GATHER_PLAN_STATISTICS */ * FROM                                     |
EMP_BIG E WHERE DEPTNO = 20   AND JOB = 'CLERK' ORDER BY EMPNO                                       |
                                                                                                     |
Plan hash value: 2894996259                                                                          |
                                                                                                     |
-----------------------------------------------------------------------------------------------------|
| Id  | Operation                   | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers ||
-----------------------------------------------------------------------------------------------------|
|   0 | SELECT STATEMENT            |             |      1 |        |  33333 |00:00:00.04 |    7159 ||
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP_BIG     |      1 |  22222 |  33333 |00:00:00.04 |    7159 ||
|*  2 |   INDEX RANGE SCAN          | EMP_BIG_X01 |      1 |  22222 |  33333 |00:00:00.02 |    3457 ||
-----------------------------------------------------------------------------------------------------|
                                                                                                     |
Predicate Information (identified by operation id):                                                  |
---------------------------------------------------                                                  |
                                                                                                     |
   2 - access("DEPTNO"=20 AND "JOB"='CLERK')                                                         |
                                                                                                     |
This post is licensed under CC BY 4.0 by the author.