본문 바로가기
Dev/Oracle

[Oracle] 10046 TRACE - 인덱스 사용

by 흰바다제비 2022. 7. 21.
728x90

테이블 정보

TEST.EMP_210825

-- TEST.EMP_210825
EMPNO         NUMBER(4)
ENAME         VARCHAR2(10)
JOB         VARCHAR2(9)
MGR         NUMBER(4)
HIREDATE          DATE
SAL         NUMBER(7,2)
COMM         NUMBER(7,2)
DEPTNO         NUMBER(2)

 

/* 데이터 1,000,000건 추가
EMPNO : 숫자 4자리
ENAME : 영어 6자리
JOB : 영어 9자리
MGR :  숫자 4자리
HIREDATE : SYSDATE
SAL : 숫자 4자리 +  첫글자만 랜덤
COMM : NULL
DEPNO = 10 */

 INSERT INTO TEST.EMP_210825 
 SELECT ROUND(DBMS_RANDOM.VALUE(1000,9999)) AS EMPNO, 
        DBMS_RANDOM.STRING('U',6) AS ENAME, 
        DBMS_RANDOM.STRING('U',9) AS JOB, 
        ROUND(DBMS_RANDOM.VALUE(1000,9999)) AS MGR, 
        SYSDATE AS HIREDATE, 
        ROUND(DBMS_RANDOM.VALUE(1, 9)) || '000' AS SAL, 
        NULL AS COMM, 
        10 AS DEPNO 
 FROM DUAL 
 CONNECT BY LEVEL < 1000000;

 

인덱스 구성

  1. EMPNO
  2. EMPNO + ENAME
  3. EMPNO + SAL
 CREATE INDEX INDEX_1 ON TEST.EMP_210825(EMPNO); 
 CREATE INDEX INDEX_2 ON TEST.EMP_210825(EMPNO, ENAME); 
 CREATE INDEX INDEX_3 ON TEST.EMP_210825(EMPNO, SAL);

실행 계획 분석 - 10046 TRACE

-- 카디널리티 확인

 SELECT COUNT(DISTINCT(EMPNO)), 
        COUNT(DISTINCT(ENAME)), 
        COUNT(DISTINCT(SAL)) 
 FROM TEST.EMP_210825; 
 C_EMPNO  C_ENAME  C_SAL 
--------  -------  ----- 
    9000   998396     19

 

(1) SQL 실행

아래 경우에 대해

  1. FULL TABLE SCAN 했을 때  10046 TRACE
  2. INDEX SCAN(INDEX_1) 했을 때 10046 TRACE
-- 1. INDEX_1 : FULL TABLE SCAN  
 SELECT /*+ NO_INDEX(A)  */  * 
 FROM TEST.EMP_210825 A 
 WHERE EMPNO = '7369';

-- 2. INDEX SCAN(INDEX_1) 
 SELECT * 
 FROM TEST.EMP_210825 A 
 WHERE EMPNO = '7369';

10046 TRACE 확인

-- SERVER PROCESS ID 확인 
 SELECT P.SPID 
 FROM V$PROCESS P, 
      V$SESSION S 
 WHERE P.ADDR = S.PADDR 
 AND S.AUDSID = USERENV('SESSIONID'); 
 ALTER SESSION SET 
 EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 1'; 
-- SQL 실행 . . . 
   
 ALTER SESSION SET SQL_TRACE=FALSE;

앞서 확인한 SPID로 TRACE 파일을 찾는다. TRACE 파일을 쉽게 볼 수 있게 변경

(ORCL)/oracle/app/oracle/diag/rdbms/orcl/ORCL/trace> tkprof ORCL_ora_2460.trc /tmp/2460.txt

 

(2) TRACE 파일 내용

1. FULL TABLE SCAN

 -- 1.
SELECT /*+ NO_INDEX(A)  */  * 
 FROM TEST.EMP_210825 A 
 WHERE EMPNO = '7369' 
call     count       cpu    elapsed       disk      query    current        rows 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
Parse        1      0.00       0.00          0          4          0           0 
Execute      1      0.00       0.00          0          0          0           0 
Fetch        2      0.01       0.01          0       4900          0         101 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
total        4      0.01       0.01          0       4904          0         101 

Misses in library cache during parse: 1 
Optimizer mode: ALL_ROWS 
Parsing user id: 9   
Number of plan statistics captured: 1 

Rows (1st) Rows (avg) Rows (max)  Row Source Operation 
---------- ---------- ----------  --------------------------------------------------- 
       101        101        101  TABLE ACCESS FULL EMP_210825 (cr=4900 pr=0 pw=0 time=23 us starts=1 cost=1716 size=17400 card=200)

2. INDEX_1

-- 2.
SELECT * 
 FROM TEST.EMP_210825 A 
 WHERE EMPNO = '7369' 
call     count       cpu    elapsed       disk      query    current        rows 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
Parse        1      0.00       0.00          0          4          0           0 
Execute      1      0.00       0.00          0          0          0           0 
Fetch        2      0.00       0.00          0        104          0         101 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
total        4      0.00       0.00          0        108          0         101 

Misses in library cache during parse: 1 
Optimizer mode: ALL_ROWS 
Parsing user id: 9   
Number of plan statistics captured: 1 

Rows (1st) Rows (avg) Rows (max)  Row Source Operation 
---------- ---------- ----------  --------------------------------------------------- 
       101        101        101  TABLE ACCESS BY INDEX ROWID EMP_210825 (cr=104 pr=0 pw=0 time=40 us starts=1 cost=2 size=17400 card=200) 
       101        101        101   INDEX RANGE SCAN INDEX_1 (cr=4 pr=0 pw=0 time=635 us starts=1 cost=1 size=0 card=200)(object id 29305)

query (메모리에서 읽은 블록의 수)가

full table scan 시 4904개, index 사용시 108개로

index를 타고 실행을 했을 때 cost 면에서 더 효율적인 것을 알 수 있다.

 


(3) TRACE 파일 내용 분석

SQL

 SELECT * 
 FROM TEST.EMP_210825 A 
 WHERE EMPNO = '7369'

Call statistics

call     count       cpu    elapsed       disk      query    current        rows 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
Parse        1      0.00       0.00          0          4          0           0 
Execute      1      0.00       0.00          0          0          0           0 
Fetch        2      0.00       0.00          0        104          0         101 
------- ------  -------- ---------- ---------- ---------- ----------  ---------- 
total        4      0.00       0.00          0        108          0         101
  • Call - Parse : SQL을 Parsing
    • Execute : SQL을 실제 Execute. DML 일 경우
    • Fetch : SQL을 통해 나온 값을 사용자에게 반환. DB Buffer Cache에 복사된 블록 중에서 사용자가 요청한 원하는 데이터만 고름
  • Count : SQL문이 parse, execute, fetch 가 수행된 횟수
  • CPU : call 작업 (parse, execute, fetch) 이 실제로 사용한 CPU 시간
  • Elapsed : 각 구간에서 시작과 종료까지 총 수행한 시간
  • Disk : Disk에서 읽은 Block의 양(Physical Read)
  • Query : Memory에 읽은 Block의 양(Logical Read)
  • Current : 현재의 Session에서 작업한 내용을 Commit하지 않아 자신에게만 유효한 Block(Dirty Block)을 액세스한 블럭 양
  • Rows : 각 단계별 액세스한 Rows

→ disk, query, current의 숫자는 적을수록 좋다.

이 숫자들이 크면 메모리 공유 영역의 적중률 (Hit ratio)이 낮다는 것을 의미

 

Misses in library cache during parse: 1 
Optimizer mode: ALL_ROWS 
Parsing user id: 9 
Number of plan statistics captured: 1
  • Misses in library cache during parse : parse 하는데 library cache에서 해당 SQL을 찾지 못함
  1. 1 : Hard parse
  2. 0 : Soft parse
  • Optimizer mode
    • first_rows : 처음 몇개의 행을 빠르게 전달하는 best plan 찾기
    • first_rows_n : 처음 n개의 행을 반환하는데 가장 response time이 좋도록 최적화
    • all_rows  : 전체 SQL문을 완료하는데 최소 리소스 사용을 목표로 함
  • Parsing user id : parsing 을 수행한 user의 id
  • Number of plan statistics captured : Oracle이 계획에 대한 정보를 기록한 실행 횟수

Row Source Operation

Rows (1st) Rows (avg) Rows (max)  Row Source Operation 
---------- ---------- ----------  --------------------------------------------------- 
       101        101        101  TABLE ACCESS BY INDEX ROWID EMP_210825 (cr=104 pr=0 pw=0 time=40 us starts=1 cost=2 size=17400 card=200) 
       101        101        101   INDEX RANGE SCAN INDEX_1 (cr=4 pr=0 pw=0 time=635 us starts=1 cost=1 size=0 card=200)(object id 29305)
  • cr = Logical block read -- > db buffer cache에서 읽은 블록 수
  • pr = 디스크 블록 읽기. physical block read
  • pw = 디스크 블록 쓰기. physical block write
  • time = 소요 시간 ( us = microsecond )
  • starts = the number of times that line in the plan started.
  • cost = 비용. (cpu 점유, disk 1/o, 수행시간 등 을 추정한 값) 클수록 성능상 좋지는 않음
  • size = 데이터 크기
  • card = (Computed) Cardinality . The estimated number of rows returned by operation

 

 

728x90

댓글