[Oracle 튜닝] 3. Wait Events 이해하기: DB는 무엇을 기다리는가?

SQL의 실행 계획을 분석하고 인덱스를 적절히 생성했지만, 데이터베이스는 여전히 느릴 때가 있습니다. 왜일까요? CPU가 열심히 일하는 시간(CPU Time) 외에, 데이터베이스 세션은 대부분의 시간을 무언가를 ‘기다리면서(Waiting)’ 보내기 때문입니다.

성능 튜닝의 마지막 퍼즐은 바로 이 **’대기 이벤트(Wait Event)’**를 분석하여, 데이터베이스가 정확히 무엇을, 왜 기다리는지 알아내는 것입니다.


Wait Event란 무엇인가? 🐢

Wait Event는 Oracle 세션이 현재 작업을 계속 진행하지 못하고 멈춰 서서 기다리고 있는 이유를 나타내는 상태 정보입니다.

  • 비유: 식당 주방에서 요리사(CPU)가 요리를 하려면 각종 재료가 필요합니다. 만약 ‘감자’라는 재료가 창고에 있다면, 요리사는 직접 창고에 가서 감자를 가져와야 합니다. 이 **’창고에 가서 감자를 가져오는 시간’**이 바로 Wait Event입니다. 요리사 자체의 요리 실력(CPU 성능)이 아무리 뛰어나도, 재료를 가져오는 시간이 길어지면 전체 요리 시간은 길어질 수밖에 없습니다.

마찬가지로 Oracle 세션은 디스크에서 데이터를 읽어오거나, 다른 세션이 사용 중인 자원이 해제되기를 기다리는 등 다양한 이유로 대기합니다. 성능 튜닝은 불필요한 대기 시간을 줄여 CPU가 쉬지 않고 일할 수 있도록 환경을 만들어주는 과정입니다.


Wait Event 확인하는 방법: V$SESSION

현재 어떤 세션들이 무엇을 기다리고 있는지 실시간으로 확인하는 가장 기본적인 방법은 V$SESSION이라는 동적 성능 뷰(Dynamic Performance View)를 조회하는 것입니다.

  • 핵심 조회 쿼리:
SELECT 
    SID, -- 세션 ID 
    SERIAL#, -- 세션 시리얼 번호 
    USERNAME, -- 접속 유저 
    STATUS, -- 세션 상태 (ACTIVE/INACTIVE) 
    EVENT, -- 현재 대기 중인 이벤트 이름! 
    SECONDS_IN_WAIT, -- 현재 이벤트를 몇 초 동안 기다렸는지 
    SQL_ID -- 실행 중인 SQL의 ID 
FROM 
    V$SESSION 
WHERE 
    USERNAME IS NOT NULL 
    AND STATUS = 'ACTIVE'; -- 현재 활성 상태인 세션만 조회 
  • 이 쿼리를 실행하면, 현재 활발하게 활동 중인 세션들이 어떤 이유(EVENT 컬럼)로 대기하고 있는지 한눈에 파악할 수 있습니다.

반드시 알아야 할 주요 Wait Events

수백 가지의 Wait Event가 있지만, 성능 문제의 원인으로 자주 지목되는 핵심 이벤트는 다음과 같습니다.

1. db file sequential read

  • 의미: 인덱스를 이용하여 디스크의 데이터 블록을 한 개씩 순차적으로 읽어올 때 발생하는 대기입니다.
  • 분석: 이 대기 시간이 길다면, 인덱스를 통한 데이터 접근이 많다는 의미입니다. 이는 정상적인 상황일 수 있지만, 비효율적인 인덱스를 너무 많이 경유하거나(예: Nested Loops Join), 데이터가 흩어져 있어 디스크 I/O가 과도하게 발생할 때 문제가 됩니다. SQL 튜닝을 통해 더 효율적인 인덱스를 사용하도록 유도하거나, I/O 성능 자체를 개선하는 방향을 고려해야 합니다.

2. db file scattered read

  • 의미: Full Table Scan 또는 Index Fast Full Scan 시, 여러 개의 데이터 블록을 한 번에 메모리로 읽어올 때 발생하는 대기입니다.
  • 분석: 이 대기 시간이 길다는 것은 대량의 데이터를 읽는 Full Scan이 빈번하게 발생하고 있다는 강력한 신호입니다. 해당 SQL의 실행 계획을 확인하여 불필요한 Full Scan이 일어나고 있는지 점검하고, 적절한 인덱스를 생성하여 db file sequential read로 전환하는 튜닝이 필요합니다.

3. log file sync

  • 의미: 사용자가 COMMIT을 실행했을 때, 변경 사항이 디스크의 리두 로그 파일(Redo Log File)에 안전하게 기록되기를 기다리는 대기입니다.
  • 분석: 이 대기 시간이 길다면 COMMIT이 너무 자주 발생하고 있거나, 로그 파일이 기록되는 디스크(I/O)의 성능이 느리다는 의미입니다. 애플리케이션 로직을 수정하여 불필요하게 잦은 COMMIT을 줄이거나, 더 빠른 디스크로 로그 파일을 이전하는 것을 고려해야 합니다.

4. latch free / enq: (락 관련 대기)

  • latch free: 메모리 구조(예: 버퍼 캐시)에 대한 접근을 제어하는 매우 가벼운 잠금 장치인 ‘래치’를 기다리는 대기입니다. 경합이 심하면 CPU 사용률이 높게 나타납니다.
  • enq: ...: 특정 행이나 테이블에 대한 락(Lock)을 다른 세션이 해제하기를 기다리는 대기입니다. ORA-00060(교착 상태)의 원인이 되기도 합니다.
  • 분석: 이 유형의 대기는 동시성(Concurrency) 문제와 직결됩니다. 특정 자원에 여러 세션이 동시에 접근하려 할 때 발생하므로, 어떤 SQL이 어떤 자원을 두고 경합하는지 파악하여 락을 유발하는 로직을 수정해야 합니다.

결론: 대기 이벤트는 성능 문제의 ‘단서’

성능 튜닝은 Wait Event를 ‘0’으로 만드는 것이 목표가 아닙니다. 데이터베이스는 필연적으로 디스크 I/O나 자원 확보를 기다릴 수밖에 없습니다. 중요한 것은 불필요하고 비정상적으로 긴 대기 시간을 유발하는 원인을 찾아내는 것입니다.

Wait Event는 데이터베이스가 우리에게 보내는 ‘어디가 아프다’는 신호이자, 성능 문제의 원인을 찾아가는 가장 중요한 단서입니다. 실행 계획 분석과 인덱스 전략에 Wait Event 분석을 더하면, 비로소 Oracle 성능 튜닝의 전체 그림을 완성할 수 있습니다.