현재 선택한 SQL 과정

SQLP 이론 학습

이론 목록으로 돌아가기

응답시간 분석: DB Time·CPU·Wait Event

대기 횟수보다 응답시간과 업무 영향에 초점을 맞춰 CPU·I/O·Concurrency·Network 병목을 분류합니다.

예상 읽기 27

핵심 요약

성능 문제는 Wait Event 이름이나 발생 횟수만으로 진단하지 않습니다. 먼저 사용자가 체감한 End-to-End Response Time과 Oracle이 Database 내부에서 집계한 DB Time의 범위를 구분한 뒤, 문제 시간대에 시간이 어디에서 소비됐는지 단계적으로 좁힙니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
End-to-End Response Time
├─ Client Rendering·처리
├─ Network 전송·왕복
├─ Application Queue·Business Logic
├─ Connection Pool·외부 API
└─ Database Call
   ├─ Database CPU 사용
   └─ Foreground Non-Idle Wait
      ├─ User I/O
      ├─ Commit
      ├─ Application Lock
      ├─ Concurrency
      ├─ Cluster
      ├─ Network
      └─ 기타 Wait Class

Oracle의 DB time은 Foreground Session이 Database Call 안에서 소비한 누적 시간입니다. 공식 정의상 CPU 시간과 Idle Class를 제외한 Wait Time을 합산합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
ΔDB Time
  ≈ ΔDB CPU
  + ΔForeground Non-Idle Wait Time

실제 보고서에서는 계측 단위·게시 지연·반올림 때문에 완전히 일치하지 않을 수 있으므로 근사 관계로 해석합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
응답시간 분석의 기본 순서

1. 문제 시간·업무·Service·Module 범위 확정
2. End-to-End에서 Database Call 비중 확인
3. ΔDB Time을 ΔDB CPU와 Foreground Wait Class로 분해
4. 총 시간이 큰 Event·SQL·Session을 확인
5. Event Parameter·Object·Blocker·실행계획과 연결
6. 한 원인만 변경하고 동일 조건으로 재측정

Wait Event는 근본 원인의 이름이 아니라 Server Process가 어떤 자원이나 작업 완료를 기다리며 시간을 소비했는지 보여 주는 관찰 지점입니다.

이 이론의 범위

이 이론은 SQLP의 SQL 고급활용 및 튜닝 → SQL 분석 도구 → 응답 시간 분석 범위에서 DB Time, CPU, Wait Event와 AAS를 다룹니다. SQL Trace·TKPROF의 Call별 상세 통계, AWR·ASH 보고서의 전체 사용법, RAC·Storage 내부 분석은 후속 이론에서 다룹니다.


학습 목표

이 이론을 학습한 뒤에는 다음 내용을 설명할 수 있어야 합니다.

  • End-to-End Response Time, Database Call Elapsed Time, DB Time의 범위를 구분한다.
  • DB Time과 DB CPU·Foreground Non-Idle Wait의 관계를 설명한다.
  • DB Time이 같은 벽시계 구간보다 클 수 있는 이유를 설명한다.
  • Time Model 통계의 단위와 Live View 게시 지연에 주의한다.
  • Average Active Sessions를 계산하고 CPU·Wait Class로 분해한다.
  • V$SESSION의 현재 Wait와 마지막 Wait를 구분한다.
  • WAIT_TIME_MICROTIME_SINCE_LAST_WAIT_MICRO를 구분한다.
  • V$SESSION_EVENT, V$SYSTEM_EVENT, V$SYSTEM_WAIT_CLASS의 관찰 범위를 구분한다.
  • Idle Wait와 Non-Idle Wait를 구분한다.
  • Wait Count·Total Time·Average·업무량당 시간을 함께 해석한다.
  • CPU 포화 여부를 DB CPU뿐 아니라 OS CPU·Run Queue와 함께 판단한다.
  • I/O·Commit·Lock·Concurrency·Network Event의 후속 진단 질문을 만든다.
  • Latch의 Gets·Misses·Spin Gets·Sleeps·Wait Time을 구분한다.
  • Bottleneck Migration을 고려해 변경 후 다시 측정한다.

1. 응답시간의 범위를 먼저 구분한다

사용자가 화면에서 측정한 8초와 Database가 기록한 시간은 같은 범위가 아닐 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
사용자 응답시간 8.0초
├─ Browser·Client 처리         0.4초
├─ Network                     0.3초
├─ Application Queue·Logic     2.0초
├─ Connection Pool Wait        1.3초
└─ Database Call               4.0초

Database Call을 50% 개선해도 전체 화면은 약 2초만 줄어듭니다. 성능 진단의 첫 단계는 측정 범위를 명확히 하는 것입니다.

범위포함하는 시간
End-to-End Response TimeClient 요청부터 최종 응답 완료까지의 전체 시간
Application TimeQueue, Business Logic, Connection Pool, 외부 API 등
Database Call Elapsed Time한 Database Call의 시작부터 완료까지의 경과시간
DB Time모든 Foreground Session이 Database Call 안에서 소비한 시간의 합
DB CPUForeground Session이 실제 CPU에서 실행한 시간
Foreground Non-Idle WaitForeground Session이 Non-Idle Event를 기다린 시간

1.1 DB Time은 사용자 한 건의 응답시간이 아니다

여러 Session이 동시에 활동하면 DB Time은 같은 벽시계 구간보다 클 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Elapsed Time = 10초
Active Session 4개가 각각 약 10초 활동
→ ΔDB Time ≈ 40초
→ AAS ≈ 4

따라서 Instance 전체 DB time 40초를 “사용자가 40초 기다렸다”라고 해석하면 안 됩니다.

1.2 Database 밖의 시간

DB Time에는 다음 시간이 직접 포함되지 않을 수 있습니다.

  • Client Rendering
  • Application Queue와 Business Logic
  • Connection Pool 대기
  • 외부 API
  • Database Call 사이의 Client Think Time
  • Client가 다음 요청을 보내기 전 Idle Time

End-to-End 지연이 큰데 DB Time·Database Call이 작다면 Application·Network 구간을 함께 조사합니다.


2. DB Time과 DB CPU·Wait의 관계

Oracle 공식 통계의 DB time은 Foreground Database Call의 CPU와 Non-Idle Wait를 집계한 Instance Workload 지표입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
ΔDB Time
  ≈ ΔDB CPU
  + Σ ΔForeground Non-Idle Wait Time

예를 들어 10분 구간의 DB Time이 1,000초라면 다음처럼 분해할 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
DB CPU                  600초
User I/O Wait           250초
Application Wait        100초
Commit Wait              30초
Concurrency Wait         20초
--------------------------------
DB Time               1,000초

이때 첫 질문은 “Disk가 느린가?” 하나가 아닙니다.

  • DB CPU 600초를 소비한 SQL·Plan·Row 처리량은 무엇인가?
  • User I/O 250초는 필요한 데이터량인가, 불필요한 Scan·Random Access인가?
  • Application Wait 100초의 Waiter·Blocker는 누구인가?
  • Commit Wait 30초는 Commit 빈도·LGWR·Redo Storage·CPU Scheduling 중 어디와 연결되는가?

2.1 DB CPU가 뜻하지 않는 것

DB CPU는 실제로 소비한 CPU Time입니다. CPU를 사용하려고 Runnable 상태로 OS Run Queue에서 기다린 시간을 직접 모두 보여 주는 지표는 아닙니다.

CPU 병목은 다음을 함께 확인합니다.

  • CPU AAS
  • Host CPU 사용률
  • Load Average·Run Queue
  • CPU Core 수
  • OS Context Switch
  • Resource Manager CPU Wait
  • SQL별 CPU Time·Executions·Rows
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
CPU AAS가 Core 수에 근접·초과
+ Host CPU 지속 포화
+ Run Queue 증가
→ CPU 경쟁 가능성 강화

Total AAS가 CPU Core 수보다 높더라도 대부분이 I/O·Lock Wait라면 CPU 포화로 바로 결론 내리지 않습니다.


3. Time Model 통계

Instance 전체 Time Model은 V$SYS_TIME_MODEL, Session 단위는 V$SESS_TIME_MODEL에서 확인합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT stat_name,
       value
FROM   v$sys_time_model
WHERE  stat_name IN ('DB time', 'DB CPU');

VALUE의 단위는 Microsecond입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
DB time  = 900,000,000 μs = 900초
DB CPU   = 540,000,000 μs = 540초

Session 단위 예시는 다음과 같습니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT sid,
       stat_name,
       value
FROM   v$sess_time_model
WHERE  sid = :sid
AND    stat_name IN ('DB time', 'DB CPU');

3.1 Live View 게시 지연

Oracle Time Model은 긴 작업 중 통계를 일정 단위로 Buffering하여 게시할 수 있으며, 공식 문서는 한 Operation에서 최대 약 5초의 미게시 시간이 있을 수 있다고 설명합니다.

현재 실행 중인 긴 Call을 초 단위로 비교할 때 작은 차이에 과도한 의미를 부여하지 않습니다.

3.2 단위를 혼합하지 않는다

View·Statistic대표 단위
V$SYS_TIME_MODEL.VALUEMicrosecond
V$SESS_TIME_MODEL.VALUEMicrosecond
V$SYSSTATDB timeCentisecond
TIME_WAITED_MICRO*Microsecond
일부 TIME_WAITEDHundredth of a second

계산 전 모든 값을 초 또는 Microsecond로 통일합니다.


4. Average Active Sessions

Average Active Sessions(AAS)는 일정 구간에 평균적으로 몇 개의 Foreground Session이 CPU를 사용하거나 Non-Idle Wait 상태였는지 나타냅니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
AAS
  = ΔDB Time(초) / Elapsed Time(초)

예를 들어 60초 동안 DB Time 증가량이 300초라면 다음과 같습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
AAS = 300 ÷ 60 = 5

평균적으로 5개의 Session이 Database에서 Active 상태였습니다.

4.1 CPU·Wait Class AAS

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
CPU AAS
  = ΔDB CPU / Elapsed

User I/O AAS
  = ΔForeground User I/O Wait / Elapsed

Application AAS
  = ΔForeground Application Wait / Elapsed

예를 들어 다음처럼 분해할 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Total AAS         5.0
├─ CPU AAS        3.0
├─ User I/O AAS   1.2
├─ Application    0.6
└─ Commit         0.2

AAS는 동시 활동량을 보여 주지만 업무별 지연 정도를 직접 나타내지는 않습니다. P95·P99 응답시간, Throughput과 함께 봅니다.


5. Wait Event와 Wait Class

Oracle Server Process는 CPU에서 계속 실행되는 것이 아니라 필요한 자원이나 작업 완료를 기다립니다. Oracle은 이 상태를 Wait Event로 기록합니다.

요소의미
Event Name기다린 작업이나 자원
Wait ClassEvent를 큰 범주로 분류
Total Waits대기 발생 횟수
Time Waited누적 대기시간
Average Wait한 번당 평균
Event ParameterFile·Block·Lock Identifier 등
SID·SQL_ID어느 Session·SQL의 대기인지
Blocking Session다른 Session이 대기를 만들었는지

Wait Class 예시는 다음과 같습니다.

Wait Class대표 의미
User I/OForeground Data Block I/O
CommitCommit Redo Flush 확인
ApplicationRow·Table Lock 등 Application 설계와 연결되는 대기
ConcurrencyLatch·Shared Buffer 등 내부 동시성 자원
ClusterRAC Global Cache·Interconnect
NetworkNetwork Message 전송
SchedulerResource Manager Queue
Idle작업이 없어 다음 요청을 기다림

Event 이름만 보고 근본 원인을 확정하지 않습니다. 같은 db file sequential read도 요청량, Storage Latency, Cache 상태와 실행계획에 따라 의미가 다릅니다.


6. Idle Wait와 Non-Idle Wait

Idle Wait는 Session이 Database 작업을 적극적으로 수행하지 않고 다음 작업을 기다리는 상태입니다.

대표적인 SQL*Net message from client는 Dedicated Server가 Client의 다음 요청을 기다린 시간을 포함합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
SQL 처리 완료
→ 결과 전송
→ Client가 다음 Call을 보낼 때까지 대기
→ SQL*Net message from client 누적

이 Event가 크다는 이유만으로 Network 병목이나 느린 SQL이라고 결론 내리지 않습니다.

Non-Idle Wait는 Database 작업 중 필요한 자원·I/O·Lock·Message 완료를 기다린 시간이며 DB Time에 포함됩니다.

Network Class의 SQL*Net more data to client, Database Link Event 등은 실제 전송량·Round Trip·Client 소비 속도와 연결할 수 있습니다. Idle Class인 SQL*Net message from client와 구분합니다.


7. 현재 Session 상태를 올바르게 읽는다

V$SESSION 또는 V$SESSION_WAIT는 현재 Wait 또는 마지막 Wait 정보를 보여 줍니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT sid,
       serial#,
       status,
       sql_id,
       state,
       event,
       wait_class,
       wait_time_micro,
       time_since_last_wait_micro,
       blocking_instance,
       blocking_session,
       final_blocking_instance,
       final_blocking_session
FROM   v$session
WHERE  sid = :sid;

7.1 현재 Wait와 마지막 Wait 구분

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
STATE = WAITING
  → EVENT는 현재 기다리는 Event
  → WAIT_TIME_MICRO는 현재 Wait에서 소비한 시간

STATE = WAITED ...
  → Session은 현재 기다리지 않음
  → EVENT는 가장 최근에 끝난 Wait Event
  → WAIT_TIME_MICRO는 마지막 Wait의 시간
  → TIME_SINCE_LAST_WAIT_MICRO는 마지막 Wait 종료 후 경과시간

Session이 STATUS='ACTIVE'여도 현재 CPU를 사용 중이거나 Database Code를 실행 중일 수 있습니다. EVENT Column에 마지막 Wait Event가 남아 있다고 현재 그 Event를 기다린다고 단정하지 않습니다.

SECONDS_IN_WAIT와 전통적인 WAIT_TIME은 Deprecated이므로 가능하면 Microsecond Column과 STATE를 사용합니다.

7.2 Blocker 확인

BLOCKING_SESSION은 직접 Blocker를, FINAL_BLOCKING_SESSION은 Wait Chain의 최종 Blocker를 찾는 데 도움을 줍니다.

RAC에서는 BLOCKING_INSTANCEFINAL_BLOCKING_INSTANCE도 함께 확인합니다.


8. Session·Instance 누적 Wait 통계

8.1 Session 누적 Event

V$SESSION_EVENT는 해당 Session이 시작된 이후 Event별 누적 Wait를 보여 줍니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT event,
       wait_class,
       total_waits,
       total_timeouts,
       time_waited_micro,
       ROUND(
         time_waited_micro / NULLIF(total_waits, 0) / 1000,
         3
       ) AS avg_wait_ms
FROM   v$session_event
WHERE  sid = :sid
AND    wait_class <> 'Idle'
ORDER BY time_waited_micro DESC;

누적값이므로 문제 작업 전후 Snapshot Delta를 사용하거나 Session 생성 시각과 업무 범위를 확인합니다.

8.2 Instance 누적 Event

V$SYSTEM_EVENT는 Instance 전체 Event 누적값을 보여 줍니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT event,
       wait_class,
       total_waits_fg,
       time_waited_micro_fg
FROM   v$system_event
WHERE  wait_class <> 'Idle'
ORDER BY time_waited_micro_fg DESC;

DB Time은 Foreground Workload 지표이므로 비교할 때 TOTAL_WAITS_FG, TIME_WAITED_MICRO_FG 같은 Foreground Column을 우선 사용하면 범위를 맞추기 쉽습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
ΔEvent Time
  = End TIME_WAITED_MICRO_FG
  - Begin TIME_WAITED_MICRO_FG

8.3 Wait Class 누적 통계

V$SYSTEM_WAIT_CLASS는 Wait Class별 Instance 누적값과 Foreground 전용 Column을 제공합니다.

SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT wait_class,
       total_waits_fg,
       time_waited_micro_fg
FROM   v$system_wait_class
WHERE  wait_class <> 'Idle'
ORDER BY time_waited_micro_fg DESC;

AAS 계산에는 같은 시간 구간의 Delta를 사용합니다.


9. 대기 횟수보다 시간을 우선한다

다음 두 Event를 비교합니다.

EventWaitsTotal Wait TimeAverage Wait
A1,000,00010초0.01ms
B10050초500ms

응답시간 영향은 B가 더 큽니다.

기본 우선순위는 다음과 같습니다.

  1. 문제 구간의 총 대기시간이 큰가
  2. Foreground 업무와 같은 시간에 발생했는가
  3. 특정 Service·Module·SQL·Session에 집중되는가
  4. 한 번당 대기가 비정상적으로 긴가
  5. 처리량 증가에 따른 정상적 증가인가
  6. DB Time·DB Call·P95 응답시간에 차지하는 비중은 얼마인가

9.1 업무량으로 정규화

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Wait Time / Transaction
Wait Time / Execution
Lock Wait / Request
Commit Wait / Commit
I/O Wait / Read Request

총 대기시간이 증가해도 처리량이 더 크게 증가했다면 건당 성능은 개선되었을 수 있습니다.

9.2 Average만으로 Outlier를 숨기지 않는다

평균 대기는 일부 긴 Wait를 가릴 수 있습니다. 간헐적인 지연은 다음 정보를 함께 확인합니다.

  • Max·P95·P99 응답시간
  • Event Histogram
  • ASH Sample의 시간대 분포
  • 특정 Blocker·SQL에 집중된 구간

10. 대표 Event의 진단 방향

10.1 User I/O

Event기본 의미다음 확인
db file sequential read일반적으로 Single Block Read 완료 대기SQL별 요청 수, File·Block, Index·ROWID 반복 접근, Storage Latency
db file scattered readBuffer Cache 경로의 Multiblock ReadFull Scan Data량, Request Block 수, 실제 Wait Time
direct path readDirect Path 비동기 읽기 완료 확인Parallel·Large Scan, Read Bytes, Outstanding I/O
direct path read tempTEMP Direct ReadSort·Hash Spill, Workarea·TEMP I/O

I/O Event가 많더라도 Time Waited가 작고 DB Time 비중이 낮다면 우선순위가 낮을 수 있습니다.

10.2 Commit

log file sync는 Synchronous Commit을 요청한 Foreground가 LGWR의 Redo Flush 확인을 기다리는 Commit Class Event입니다.

다음 항목을 함께 확인합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
User Commits/초
Commit Wait/Commit
Redo Size/초
log file parallel write
LGWR CPU Scheduling
Redo Storage Latency
행·Row마다 Commit하는 Application 패턴

log file parallel write가 낮은데 log file sync가 높다면 Foreground·LGWR CPU Scheduling, Post 지연, Commit 폭증 등도 조사합니다.

10.3 Application Lock

enq: TX - row lock contention에서는 다음을 확인합니다.

  • Waiter·Blocker와 Final Blocker
  • Blocker Transaction 시작 시각
  • 미완료 Transaction
  • 같은 Row·Unique Key 접근
  • Application 갱신 순서
  • Transaction 범위와 사용자 Think Time

enq: TM - contention에서는 Lock Mode, DDL·DML 충돌, Foreign Key Index 누락 가능성 등을 원인 후보로 확인합니다. Event 이름만으로 Foreign Key가 원인이라고 확정하지 않습니다.

10.4 Concurrency

buffer busy waits, Latch·Mutex Event에서는 다음을 확인합니다.

  • Hot Block·Segment Header·Index Leaf 집중
  • 많은 Session의 같은 Block 동시 접근
  • Hard Parse·Shared Pool 자료구조 경합
  • CPU 포화 상태에서 Spin 비용
  • Event별 Wait Time과 SQL·Object 집중도

10.5 Network

Network 문제는 다음을 구분합니다.

  • Client가 다음 Call을 보내지 않는 Idle
  • Server가 많은 Row·Byte를 Client로 전송
  • 작은 Fetch Size로 Round Trip 과다
  • Database Link 전송
  • Client가 Result를 늦게 소비
  • 실제 Network Latency·Packet Loss

SQL*Net message from client 누적시간만으로 Network 병목을 진단하지 않습니다.


11. Latch·Mutex 경합

Latch는 Shared Memory 자료구조를 짧게 보호하는 동기화 장치입니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Latch 획득 시도
  → 즉시 획득
  → 첫 시도 실패(Miss)
     → CPU에서 짧게 Spin
        → Spin 중 획득(Spin Get)
        → 계속 실패
           → Sleep·Wait
           → 재시도

대표 통계는 다음과 같습니다.

지표의미
GETSWilling-to-wait 획득 요청
MISSES첫 시도에서 바로 획득하지 못한 요청
SPIN_GETSMiss 후 Spin 중 획득 성공
SLEEPSSpin 후에도 획득하지 못해 Sleep한 횟수
WAIT_TIMELatch를 기다린 누적시간
SQL코드 영역 안에서 좌우로 이동할 수 있습니다.
SELECT name,
       gets,
       misses,
       spin_gets,
       sleeps,
       wait_time
FROM   v$latch
ORDER BY wait_time DESC;

SLEEP1~SLEEP11 같은 과거 세부 Column은 현대 버전에서 Deprecated이며 값이 누적되지 않을 수 있으므로 Aggregate SLEEPS, Wait Event·Histogram을 사용합니다.

Mutex는 별도 구조와 Event를 사용하므로 Latch Ratio 공식을 그대로 적용하지 않습니다. 핵심은 Ratio보다 실제 Wait Time과 상위 원인입니다.


12. 응답시간 분해 사례

주문 저장 API의 Database Call이 10초 걸렸다고 가정합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
DB CPU                              1.2초
enq: TX - row lock contention       7.5초
log file sync                       0.8초
기타 Foreground Non-Idle Wait       0.5초
-----------------------------------------
Database Call Elapsed              10.0초

진단 순서는 다음과 같습니다.

  1. Row Lock Wait가 응답시간의 대부분임을 확인합니다.
  2. BLOCKING_SESSION·FINAL_BLOCKING_SESSION을 찾습니다.
  3. Blocker Transaction의 시작 시각·SQL·업무를 확인합니다.
  4. Transaction 범위와 갱신 순서를 점검합니다.
  5. 변경 후 같은 동시 요청 조건에서 Lock Wait와 P95를 재측정합니다.

이 상황에서 Buffer Cache 크기나 Index 추가를 첫 조치로 선택하면 핵심 병목과 연결되지 않을 수 있습니다.


13. CPU 중심 사례

5분 구간의 수치가 다음과 같다고 가정합니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Elapsed             300초
DB Time           2,400초  → Total AAS 8
DB CPU            2,100초  → CPU AAS 7
Foreground Wait     300초  → Wait AAS 1
Host CPU             95%
CPU Core               8
Run Queue 지속 증가

CPU AAS가 Core 수에 근접하고 Host CPU·Run Queue도 높으므로 CPU 포화 가능성이 큽니다.

다음 순서로 확인합니다.

  1. SQL별 CPU Time·Execution·Rows
  2. Parse CPU와 Hard Parse
  3. 불필요한 Logical I/O·Function·Row 처리
  4. Parallel Degree
  5. OS Process별 CPU와 Run Queue
  6. Resource Manager Queue 여부

CPU 증설 전에 불필요한 SQL 작업량을 줄일 수 있는지 확인합니다.


14. Bottleneck Migration

가장 큰 병목을 제거하면 다음 병목이 드러날 수 있습니다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
변경 전
  Row Lock Wait 70%
  CPU           15%
  Commit        10%
  기타           5%

Lock 개선 후
  CPU           50%
  Commit        30%
  User I/O      15%
  기타           5%

이는 변경이 실패했다는 뜻이 아닙니다. 전체 응답시간이 줄었는지 확인하고 새로 가장 큰 병목을 다시 분석합니다.


15. 실전 진단 순서

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
1. 문제 시작·종료 시각, Service·Module·Action·업무를 확정한다.
2. End-to-End에서 Database Call 비중을 분리한다.
3. 같은 구간 ΔDB Time·ΔDB CPU를 계산한다.
4. Foreground Wait Class Delta와 AAS를 계산한다.
5. 총 시간이 큰 Event·SQL·Session을 찾는다.
6. V$SESSION에서 현재 Wait와 마지막 Wait를 STATE로 구분한다.
7. Event Parameter·Object·Blocker·실행계획을 연결한다.
8. CPU 병목은 OS CPU·Run Queue와 함께 검증한다.
9. Wait·CPU를 Transaction·Execution·Commit당으로 정규화한다.
10. 한 원인만 변경하고 Throughput·P95·P99·DB Time을 재측정한다.
11. Bottleneck Migration을 확인한다.

좋은 분석 문장은 다음처럼 시간과 원인을 연결합니다.

10분 구간의 AAS는 6.2였고 이 중 Application Wait AAS가 4.1이었다. enq: TX - row lock contention의 Foreground Wait Time 2,460초가 주문 저장 Service의 세 SQL_ID에 집중됐으며, Final Blocker는 동일한 장기 Transaction이었다. 따라서 Storage나 Cache보다 Transaction 범위와 갱신 순서 개선이 우선이다.


16. 자주 혼동하는 판단

혼동하기 쉬운 판단정확한 기준
DB Time은 사용자 한 건의 응답시간이다모든 Foreground Session의 Database 활동 누적시간이다
DB Time은 벽시계 시간보다 작아야 한다동시 Session 때문에 더 클 수 있다
DB Time = DB CPU + 모든 WaitIdle을 제외한 Foreground Wait 범위를 맞춘다
V$SESSION의 EVENT는 항상 현재 Wait다STATE가 WAITING이 아니면 마지막 Wait일 수 있다
SECONDS_IN_WAIT만 보면 된다Deprecated이며 WAIT_TIME_MICRO·TIME_SINCE_LAST_WAIT_MICRO를 사용한다
Wait 횟수가 가장 크면 최우선이다문제 구간의 Foreground Total Time과 업무 영향을 우선한다
Average Wait가 낮으면 Outlier가 없다Histogram·P95·ASH 구간을 확인한다
SQL*Net message from client가 크면 Network 병목이다Client의 다음 Call을 기다리는 Idle Time이 일반적이다
CPU Time이 크면 CPU 증설부터 한다SQL 작업량과 OS 포화를 함께 확인한다
Latch Miss Ratio만 낮추면 된다SLEEPS·WAIT_TIME과 상위 SQL·Hot Resource를 확인한다
한 병목을 제거하면 진단이 끝난다Bottleneck Migration 후 다시 측정한다

17. 핵심 정리

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
End-to-End
  ≠ DB Time

DB Time
  ≈ DB CPU + Foreground Non-Idle Wait

AAS
  = ΔDB Time / Elapsed

현재 Wait
  → V$SESSION.STATE = WAITING

누적 Wait
  → V$SESSION_EVENT·V$SYSTEM_EVENT
  → 동일 구간 Delta
  → Foreground Column 우선

진단 우선순위
  → Wait Count보다 Total Time
  → Event 이름보다 SQL·Object·Blocker
  → Ratio보다 응답시간·Throughput

CPU
  → DB CPU + CPU AAS + Host CPU + Run Queue

Latch
  → Miss·Spin·Sleep·Wait Time

응답시간 분석의 목적은 Wait Event를 암기하는 것이 아닙니다. 사용자 지연 중 Database가 차지한 범위를 찾고, Database 안에서 CPU와 어느 Non-Idle Wait에 시간이 집중됐으며, 그 시간을 만든 SQL·자원·Transaction 구조를 설명하는 것이 핵심입니다.


스스로 확인하기

개념 확인 문제

문제를 누르면 바로 아래에서 정답과 해설을 확인할 수 있습니다.

01End-to-End Response Time, Database Call Elapsed Time, DB Time의 차이를 설명하시오.
정답 및 해설

시간 범위

  • End-to-End Response Time은 Client 요청부터 최종 응답까지 Network, Application, Pool, Database Call을 모두 포함합니다.
  • Database Call Elapsed는 한 Database Call의 벽시계 경과시간입니다.
  • DB Time은 모든 Foreground Session이 Database Call 안에서 CPU 사용 또는 Non-Idle Wait로 소비한 누적시간입니다.
  • 여러 Session이 동시에 활동하면 DB Time은 같은 Elapsed보다 클 수 있습니다.
02DB Time과 DB CPU·Foreground Non-Idle Wait의 관계 및 완전히 일치하지 않을 수 있는 이유를 설명하시오.
정답 및 해설

DB Time 분해

  • ΔDB Time ≈ ΔDB CPU + ΔForeground Non-Idle Wait
  • Idle Wait는 제외합니다.
  • Live Time Model의 게시 지연, 측정 정밀도, 단위 반올림 때문에 계산값이 완전히 일치하지 않을 수 있습니다.
03V$SYSTIMEMODEL과 V$SYSSTAT의 DB Time 단위 차이를 설명하시오.
정답 및 해설

단위

  • V$SYS_TIME_MODEL.VALUE는 Microsecond입니다.
  • V$SYSSTATDB time은 Centisecond입니다.
  • 비교 전 같은 단위로 변환해야 합니다.
0460초 동안 DB Time이 300초, DB CPU가 180초라면 Total AAS와 CPU AAS를 계산하시오.
정답 및 해설

AAS 계산

  • Total AAS = 300 ÷ 60 = 5
  • CPU AAS = 180 ÷ 60 = 3
  • 나머지 Wait AAS는 약 2입니다.
05V$SESSION.STATE, EVENT, WAITTIMEMICRO, TIMESINCELASTWAITMICRO를 이용해 현재 Wait와 마지막 Wait를 구분하시오.
정답 및 해설

현재·마지막 Wait

  • STATE='WAITING'이면 EVENT는 현재 Event이고 WAIT_TIME_MICRO는 현재 Wait 시간입니다.
  • STATE가 WAITED ...이면 EVENT는 가장 최근 완료된 Wait이고 WAIT_TIME_MICRO는 마지막 Wait 시간입니다.
  • TIME_SINCE_LAST_WAIT_MICRO는 마지막 Wait 종료 후 경과시간이며 현재 Wait 중에는 0입니다.
06V$SESSIONEVENT, V$SYSTEMEVENT, V$SYSTEMWAITCLASS의 범위와 Delta 사용 이유를 설명하시오.
정답 및 해설

누적 View

  • V$SESSION_EVENT는 Session Lifetime의 Event별 누적값입니다.
  • V$SYSTEM_EVENT는 Instance 전체 Event 누적값이며 DB Time과 비교할 때 Foreground Column을 사용합니다.
  • V$SYSTEM_WAIT_CLASS는 Wait Class별 Instance 누적값을 제공합니다.
  • 문제 구간의 증가량을 보기 위해 시작·종료 Delta를 계산합니다.
07SQLNet message from client를 일반 SQL 병목에서 Idle로 분리하는 이유를 설명하시오.
정답 및 해설

SQL*Net message from client

  • Dedicated Server가 Client의 다음 Call을 기다리는 Idle Time을 포함합니다.
  • Session이 오래 연결돼 있으면 값이 커질 수 있지만 Database 내부 작업 지연을 뜻하지 않을 수 있습니다.
  • 실제 Network 병목은 전송 Event, Byte, Round Trip과 Client 소비 속도를 확인합니다.
08log file sync, enq: TX - row lock contention, db file sequential read에서 각각 다음으로 확인할 항목을 작성하시오.
정답 및 해설

대표 Event 후속 확인

  • log file sync: Commit 수, Commit당 Wait, log file parallel write, Redo Size, LGWR CPU·Storage를 확인합니다.
  • enq: TX - row lock contention: Waiter·Blocker·Final Blocker, Transaction 시작 시각, SQL, 갱신 순서와 Commit 범위를 확인합니다.
  • db file sequential read: SQL별 Single Block Request 수, File·Block, Index·ROWID 반복 접근, Storage Latency와 Wait Time을 확인합니다.
09Latch의 Gets·Misses·Spin Gets·Sleeps·Wait Time을 설명하시오.
정답 및 해설

Latch 통계

  • Gets: Willing-to-wait 획득 요청입니다.
  • Misses: 첫 시도에서 바로 획득하지 못한 요청입니다.
  • Spin Gets: Miss 후 CPU Spin 중 획득 성공한 횟수입니다.
  • Sleeps: Spin 후에도 실패해 Session이 Sleep한 횟수입니다.
  • Wait Time: 실제 Latch 대기 누적시간입니다.
  • Ratio보다 Sleeps·Wait Time과 상위 원인을 확인합니다.
1010분 구간에 DB Time 3,600초, DB CPU 600초, Application Wait 2,400초, User I/O 400초, Commit 200초가 발생했다. AAS를 분해하고 우선 진단 대상을 설명하시오.
정답 및 해설

10분 구간 분석 - Elapsed = 600초 - Total AAS = 3,600 ÷ 600 = 6 - CPU AAS = 600 ÷ 600 = 1 - Application AAS = 2,400 ÷ 600 = 4 - User I/O AAS = 400 ÷ 600 ≈ 0.67 - Commit AAS = 200 ÷ 600 ≈ 0.33 - Application Wait가 AAS 4로 가장 크므로 Lock·Waiter·Blocker·Transaction 범위를 우선 진단합니다.