I/O 와 액세스
| 액세스(Access) | I/O | |
|---|---|---|
| 행위 | 데이터를 찾아가는 논리적 과정 | 디스크에서 블록을 읽어오는 물리적 행위 |
| 결국 | 어디를 읽을 것인가? | 어떻게 읽어올 것인가? |
I/O 의 기본 종류
| 분류 기준 | 유형 | 설명 | 주요 발생 상황 |
|---|---|---|---|
| 물리적 순서 | Random I/O | 디스크 헤더가 불연속적인 위치로 이동하며 읽음 | 인덱스 엔트리를 통한 테이블 블록 액세스 |
| 물리적 순서 | Sequential I/O | 인접한 블록들을 물리적 순서대로 쭉 읽음 | Full Table Scan, 로그 기록(Redo Log) |
| 읽기 단위 | Single Block I/O | 한 번의 I/O 호출로 1개의 블록만 읽음 | Index Root/Branch 탐색, 유니크 인덱스 스캔 |
| 읽기 단위 | Multi Block I/O | 한 번의 I/O 호출로 여러 블록을 읽음 | Full Table Scan, Index Fast Full Scan |
- 랜덤 / 시퀀셜
- ‘데이터에 접근하는 방식(논리/물리)’
- SingleBlock / MultiBlock
- ‘한 번에 읽어오는 단위(양)’
조합은 대부분 아래로 발생한다.
| 조합 | Random I/O | Sequential I/O |
|---|---|---|
| Single Block I/O | Multi Block I/O | |
| 특징 | 전형적인 인덱스 스캔 | Full Table Scan |
| 물리적으로 여기저기 흩어진 블록을 하나씩 찾아 읽음 | 물리적으로 인접한 블록들을 db_file_multiblock_read_count 설정값만큼 한꺼번에 읽는다 | |
| 데이터 정밀도가 높을 때 유리하다 | 개별 블록 방문 비용은 낮다 | |
| 읽어야 할 양이 많아지면 디스크 헤더의 이동 부하(Seek Time)로 인해 성능이 급격히 저하된다 | 하지만 불필요한 데이터까지 모두 읽는 단점 | |
| 대기 이벤트 | db file sequential read | db file scattered read |
ⓐ 예외적인 경우: 시퀀셜 + 싱글블럭
- 시퀀셜하게 읽더라도 싱글블럭 I/O가 발생하는 경우가 있다.
- ex) 인덱스를 처음부터 끝까지 순서대로 읽는 Index Full Scan
- 인덱스 리프 블록들은 논리적으로는 연결(Linked List)되어 있다.
- 하지만 물리적으로는 떨어져 있을 수 있다.
- 때문에 오라클은 이를 싱글블럭 I/O로 처리한다.
랜덤 / 시퀀셜
| 랜덤 액세스 | 시퀀셜 액세스 | |
|---|---|---|
| 실제 I/O 성격 | 랜덤 I/O (거의 1:1 대응) | 시퀀셜 I/O (부분적 대응) |
| 인덱스 스캔 (랜덤) | 풀 스캔 (시퀀셜) | |
| 레코드 하나를 읽기 위해 인덱스를 타고 ROWID를 찾아가 테이블 블록을 찍는 행위 ※1 | 테이블의 시작부터 끝까지 논리적으로 이어진 블록들을 순서대로 읽는 행위 (Full Table Scan) ※2 | |
| 오라클 I/O | Single Block I/O | Multi-Block I/O |
| 대기 이벤트 이름 | db file sequential read (랜덤 I/O의 대기 이벤트) | db file scattered read (여러 블록을 읽어 메모리 여기저기에 흩뿌려 저장한다는 의미) |
- ※1: 특정 지점의 블록 하나만 콕 집어서 읽으므로, 디스크 입장에서는 헤드를 계속 움직여야 하는 랜덤 I/O가 된다.
- ※2: 한 번의 시스템 콜로 연속된 여러 블록을 통째로 긁어오므로, 디스크 입장에서는 헤드의 이동을 최소화하는 시퀀셜 I/O가 된다.
오라클 이벤트 이름이 좀 비직관적이므로 주의해야 한다.
시퀀셜 액세스 vs 랜덤 액세스
시퀀셜 액세스는 논리적 / 물리적으로 연결된 순서에 따라 차례로 블록을 읽어나가는 방식이다. 인덱스와 테이블을 스캔할 때 이 방식을 사용한다.
랜덤 액세스는 논리적 / 물리적인 순서를 따르지 않고, 레코드 하나를 읽기 위해 한 블록씩 접근 (=touch) 하는 방식이다. 인덱스를 스캔하면서 얻은 rowid 로 테이블 블록을 액세스할 때 이 방식을 사용한다.
인덱스를 스캔하면서 얻은 rowid 로 테이블 블록을 액세스하는 단계가 랜덤 액세스에 해당한다.
Single Block I/O, Multiblock I/O
Single Block I/O를 이용할 때는 기본적으로 인덱스와 테이블 블록 모두 Single Block I/O 방식으로 I/O를 수행한다. 구체적으로 아래 오퍼레이션이 Single Block I/O 대상이다. 인덱스는 소량 데이터를 읽을 때 주로 사용하므로 이 방식이 효율적이다.
- 인덱스 루트 블록을 읽을 때
- 인덱스 루트 블록에서 얻은 주소 정보로 브랜치 블록을 읽을 때
- 인덱스 브랜치 블록에서 얻은 주소 정보로 리프 블록을 읽을 때
- 인덱스 리프 블록에서 얻은 주소 정보로 테이블 블록을 읽을 때
Multiblock I/O는 캐시에서 찾지 못한 특정 블록을 읽으려고 I/O Call을 할 때, 디스크 상에서 그 블록과 ‘인접한’ 블록들을 한꺼번에 읽어 캐시에 미리 적재하는 기능이다. Multiblock I/O 단위는 db_file_multiblock_read_count 파라미터에 의해 결정된다.
여기서 “인접한 블록”이란 같은 익스텐트(Extent) 에 속한 블록을 의미한다. Multiblock I/O 방식으로 읽더라도 익스텐트 경계를 넘지 못한다.
예를 들어 한 익스텐트에 20개 블록이 담겨 있고 Multiblock I/O 단위가 8이라고 할 때,
- 첫 번째 I/O Call: 8개 블록
- 두 번째 I/O Call: 8개 블록
- 세 번째 I/O Call: 남은 4개 블록만 읽음
이때 8개를 채우기 위해 다음 익스텐트까지 추가로 읽지는 않는다.
풀이 테이블을 Full Scan 하거나 인덱스를 Fast Full Scan 할 때는 Multiblock I/O 방식으로 수행한다.
db file sequential read 대기 이벤트는 Single Block I/O 할 때 나타난다.
(시퀀셜 액세스)
Multiblock I/O로 수행할 때는 db file scattered read 대기 이벤트가 나타난다.
Multiblock I/O는 한 익스텐트 안에서 이루어진다. 즉, 한 익스텐트에 속한 마지막 블록을 읽는 경우 아직 Multiblock I/O 단위를 채우지 못했더라도 다음 익스텐트를 추가로 읽지 않는다. 따라서 작은 익스텐트로 구성된 테이블을 Full Table Scan 하면 I/O Call이 더 많이 발생한다. 반면 인덱스를 이용해 테이블을 읽을 때는 Single Block I/O 방식이므로, 익스텐트 크기에 따라 I/O Call 횟수가 달라지지 않는다.
병렬 쿼리(처리)를 자주 수행하면 CPU와 메모리 자원을 많이 사용하고, 잦은 체크포인트 수행으로 LGWR 의 작업량이 증가해 커밋 성능이 지연되는 등 온라인 트랜잭션 처리(OLTP)에 나쁜 영향을 줄 수 있다.
I/O 추가 분류 체계
| 분류 층위 | 구분 키워드 | 성능 및 특징 |
|---|---|---|
| 작업 동기화 | Synchronous vs Asynchronous | I/O 완료 대기 여부 |
| OS 개입 | Buffered I/O vs Direct I/O | OS 페이지 캐시 사용 여부 |
| 저장 위치 | Permanent vs Temporary | 데이터 파일 vs Temp 파일 |
| 메모리 경로 (비주류) | Buffered vs Direct Path | 버퍼 캐시(SGA) 사용 여부 |
① 동기화 방식에 따른 분류
I/O 요청을 보낸 후 프로세스가 대기하느냐, 아니면 다른 업무를 보느냐의 차이다.
-
Synchronous I/O (동기):
- 프로세스가 디스크에 I/O를 요청하고, 데이터가 메모리에 적재될 때까지 다음 작업을 멈추고 기다린다. 대부분의 일반적인 읽기 작업이 여기에 해당한다.
-
Asynchronous I/O (비동기):
-
프로세스가 I/O 요청만 던져두고 즉시 다른 작업을 수행한다. 나중에 커널이 I/O 완료를 통보해주면 결과를 확인한다.
-
**DBWR(Database Writer)**이 체크포인트 시 데이터를 디스크에 쓸 때 주로 사용하며, 성능 최적화의 핵심이다.
-
② OS 캐시 사용 여부에 따른 분류
OS 레벨의 파일 시스템 캐시(Page Cache)를 거치느냐의 차이다.
- Buffered I/O (Cooked):
- DB가 보낸 I/O 요청이 OS의 파일 시스템 캐시에 먼저 저장된다.
- 메모리를 이중으로 사용(Double Buffering)하게 되어 비효율적일 수 있다.
- Direct I/O (Raw):
- OS 커널의 페이지 캐시를 건너뛰고 디스크에 직접 액세스한다.
- 주의:
- 오라클의 Direct Path I/O와 용어가 비슷하지만 다르다. ‘Direct I/O’는 OS 캐시를 무시하는 기술이고, ‘Direct Path I/O’는 DB 내부의 버퍼 캐시를 무시하는 기술이다. (보통 오라클 설정 시
filesystemio_options = SETALL로 두면 이 기능이 활성화된다.)
- 오라클의 Direct Path I/O와 용어가 비슷하지만 다르다. ‘Direct I/O’는 OS 캐시를 무시하는 기술이고, ‘Direct Path I/O’는 DB 내부의 버퍼 캐시를 무시하는 기술이다. (보통 오라클 설정 시
③ 영속성 및 용도에 따른 분류: Permanent vs Temporary
I/O가 발생하는 대상 파일의 성격에 따른 분류다.
- Permanent I/O:
- 실제 테이블 데이터 파일(
.dbf)이나 로그 파일에 대한 I/O다. 데이터가 영구히 보존되어야 한다.
- 실제 테이블 데이터 파일(
- Temporary I/O:
- 대량 정렬(Sort)이나 해시 조인(Hash Join) 중 메모리가 부족하여 Temp Tablespace(
.tmp)에 데이터를 썼다 읽는 I/O다. - AWR 리포트에서
direct path read temp/direct path write temp로 표시되며, 이는 서비스 쿼리 성능 저하의 주범이 된다.
- 대량 정렬(Sort)이나 해시 조인(Hash Join) 중 메모리가 부족하여 Temp Tablespace(
| 분류 층위 | 구분 항목 | 핵심 키워드 |
|---|---|---|
| I/O 발생 위치 | Logical vs Physical | 메모리(LIO)냐 디스크(PIO)냐 |
| I/O 접근 경로 | Buffered vs Direct Path | 버퍼 캐시를 경유하느냐 우회하느냐 |
| I/O 처리 단위 | Single vs Multi | 한 번에 1개냐 여러 개냐 |
| I/O 물리 패턴 | Random vs Sequential | 헤더가 점프하느냐 순차 이동하느냐 |
| I/O 정합성 모드 | Consistent vs Current | 과거 시점이냐 현재 최신 시점이냐 |
① Logical I/O vs Physical I/O (가장 상위의 분류)
모든 I/O 논의의 출발점
- Logical I/O (LIO):
- 프로세스가 필요한 데이터 블록을 찾기 위해 버퍼 캐시(SGA) 를 뒤지는 행위
- 실제 디스크로 가지 않더라도 CPU를 소모하며 래치(Latch)를 잡기 때문에, 과도한 LIO는 시스템 전체 성능을 떨어뜨린다.
- Physical I/O (PIO):
- 버퍼 캐시에 데이터가 없어 디스크에서 블록을 읽어오는 행위
- 싱글/멀티블럭, 랜덤/시퀀셜 분류는 바로 이 PIO가 발생할 때 정의되는 성질들
② Consistent Read vs Current Read (데이터 정합성 분류)
데이터를 읽을 때 ‘과거 시점’을 읽느냐 ‘현재 시점’을 읽느냐의 차이다.
- Consistent Read (CR):
- 쿼리가 시작된 시점의 스냅샷을 읽는 방식
- 내가 읽는 중에 다른 사람이 데이터를 수정했다면, 언두(Undo) 데이터를 찾아가서 과거 상태의 블록을 재구성해 읽는다.
- 대부분의
SELECT문이 여기에 해당
- Current Read (CU):
- 데이터를 수정하거나 삭제하기 위해 블록의 현재 최신 상태를 읽는 방식
INSERT,UPDATE,DELETE시 발생- 블록에 배타적 잠금(Lock)을 걸기 위한 필수 단계다.
EXTENT 와 I/O CALL 관계
테이블이 작은 EXTENT 로 구성되어 있을수록 더 많은 IO CALL 이 발생한다.
오라클은 한 번의 I/O Call로 여러 블록을 읽어올 때 익스텐트 경계를 넘어설 수 없기 때문이다.
Full Table Scan을 수행할 때 db_file_multiblock_read_count 파라미터에 지정된 수만큼 블록을 한 번에 읽는다. 이때, 아래의 물리적 제약에 따른다.
- 익스텐트 경계 준수:
- 한 번의 I/O Call은 하나의 익스텐트 내에 존재하는 블록들만 담을 수 있다.
익스텐트는 논리적으로는 연속되어 보일 수 있으나, 물리적으로는 디스크의 전혀 다른 위치에 분산되어 저장될 수 있다. 따라서 OS 레벨에서 한 번의 시스템 콜로 서로 다른 위치의 데이터를 긁어오는 것은 불가능하다.
테이블 블록이 128개, db_file_multiblock_read_count 가 64 라면
- 큰 익스텐트로 구성된 경우 (128블록 1개 익스텐트)
- I/O CALL 횟수 2회
- 작은 익스텐트로 구성된 경우 (8블록씩 16개 익스텐트)
- I/O CALL 횟수 16회
따라서 익스텐트가 작게 쪼개져 있을수록(즉, 익스텐트 개수가 많을수록) 다음과 같은 오버헤드가 발생한다.
- System Call 증가:
- I/O를 요청할 때마다 발생하는 OS 커널 호출 횟수가 늘어나 CPU 사용량이 증가한다.
- 대기 이벤트 증가:
db file scattered read대기 이벤트의 발생 횟수가 빈번해진다.- 이는 곧 전체 쿼리 수행 시간(Elapsed Time)의 증가로 이어진다.
- 딕셔너리 부하:
- 익스텐트가 너무 많으면 해당 세그먼트를 관리하는 메타데이터(Data Dictionary) 조회 및 관리 비용도 미세하게 증가한다.
오라클 내부적으로는 아래로 해당 부하를 관리한다.
- LMT (Locally Managed Tablespace):
- 익스텐트 할당 정보를 비트맵으로 관리하여 딕셔너리 부하를 최소화한다.
- Uniform Size:
- 테이블스페이스 생성 시 익스텐트 크기를 1MB 등으로 균일하게 설정
- 너무 작은 익스텐트가 무분별하게 생성되는 것을 방지한다.
db_file_multiblock_read_count
무조건 크게 설정하면 위험하다.
① 옵티마이저의 실행 계획 왜곡 (가장 치명적)
오라클의 Cost-Based Optimizer(CBO)는 쿼리 실행 비용을 계산할 때 MBRC 값을 참조한다.
- FTS 비용 감소:
- MBRC 값이 커질수록 옵티마이저는 “한 번에 많은 블록을 읽을 수 있으니 Full Scan이 저렴하다”고 판단한다.
- 인덱스 기피 현상:
- 원래는 인덱스 스캔(Index Range Scan)이 유리한 쿼리임에도 불구하고, 과도하게 높게 설정된 MBRC 때문에 옵티마이저가 비효율적인 Full Table Scan을 선택하게 된다. 이로 인해 특정 SQL의 성능이 급격히 저하될 수 있다.
② OS 및 하드웨어의 물리적 한계
MBRC를 아무리 크게 설정해도 OS 레벨의 **최대 I/O 크기(Max I/O Size)**를 넘을 수 없다.
- 예를 들어, OS의 최대 I/O 크기가 1MB이고 블록 크기가 8KB라면, 실제 물리적인 최대 MBRC는 128이다.
- 만약 MBRC를 512로 설정하더라도, 오라클은 OS 한계에 맞춰 I/O를 쪼개서 요청하게 된다. 즉, 설정값만큼의 성능 이득은 보지 못하면서 옵티마이저의 비용 계산만 왜곡시키는 결과(1번 항목)를 초래한다.
③ 버퍼 캐시 경합 및 효율성 저하
-
버퍼 캐시 점유: 대량의 블록이 한꺼번에 버퍼 캐시로 유입되면, 기존에 메모리에 상주하며 재사용되던 ‘Hot Block’들이 캐시에서 밀려나는(Age out) 현상이 가속화된다.
-
래치 경합: 많은 블록을 한꺼번에 메모리에 적재하고 관리하기 위해
cache buffers chains래치 등에 대한 경합이 증가하여 시스템 전체의 동시성이 떨어진다.
④ 현대 오라클의 자동 관리 기능과의 충돌
오라클 10g R2부터는 MBRC를 명시적으로 설정하지 않으면, 시스템 통계와 하드웨어 역량을 고려하여 오라클이 자동으로 최적값을 결정한다.
-
사용자가 이 값을 수동으로 너무 크게 고정해버리면, 오라클이 워크로드에 따라 I/O 효율을 스스로 튜닝하는 메커니즘을 방해하게 된다.
-
특별한 이유가 없다면 파라미터를 삭제하거나 자동 설정에 맡기는 것이 권장된다.
SQL SERVER 에서는
SQL Server는 동작이 다르다. SQL Server는 익스텐트 경계에 덜 종속적이며, 더 유연한 **Read-Ahead(미리 읽기)** 메커니즘을 사용하기 때문이다.
SQL Server에서는 익스텐트가 작아서 I/O Call이 늘어나는 것이 아니라, **물리적인 파편화(Fragmentation)**가 심할 때 I/O 효율이 떨어진다.
- 실제로 SQL SERVER 에서는 익스텐트 크기가 64KB 로 고정이다.
| 항목 | Oracle | SQL Server |
|---|---|---|
| 익스텐트 크기 | 가변적 (수 KB ~ 수 GB) | 64KB 고정 (8페이지) |
| I/O 단위 | 익스텐트 경계 내에서 Multi-Block I/O | Read-Ahead (여러 익스텐트 결합 가능) |
| I/O 제약 | 익스텐트 경계를 절대 넘을 수 없음 | 물리적으로 연속되면 익스텐트 경계 무시 가능 |
| 성능 저하 원인 | 작은 익스텐트가 너무 많을 때 | 익스텐트들이 물리적으로 흩어져 있을 때 (파편화) |
버퍼캐시 탐색 메커니즘
DIRECT PATH I/O 를 제외한 모든 블록 I/O 는 메모리 버퍼캐시를 경유한다. 구체적으로, 아래 오퍼레이션은 모두 버퍼캐시 탐색 과정을 거친다.
- 인덱스 루트 블록을 읽을 때
- 인덱스 루트 블록에서 얻은 주소 정보로 브랜치 블록을 읽을 때
- 인덱스 브랜치 블록에서 얻은 주소 정보로 리프 블록을 읽을 때
- 인덱스 리프 블록에서 얻은 주소 정보로 테이블 블록을 읽을 때
- 테이블 블록을 FULL SCAN 할 때
병렬 프로세스로 테이블을 FULL SCAN 할 때는 DIRECT PATH I/O 가 작동하므로 버퍼캐시를 경유하지 않는다.
버퍼캐시 히트율 (BHCR)
BHCR = (캐시에서 곧바로 찾은 블록수 / 총 읽은 블록수) * 100 = ((논리적 I/O - 물리적 I/O) / 논리적 I/O) * 100 = 1-(물리적 I/O / 논리적 I/O) * 100
논리적 I/O 는 SQL 수행 과정에 읽은 총 블록수를 말한다.
- QUERY 항목 (CONSISTENT 모드로 읽은 블록수)
- CURRENT 항목 (CURRENT 모드로 읽은 블록수)
- 을 더해서 구한다.
읽고자 하는 블록을 먼저 캐시에서 찾고, 못 찾으면 디스크에서 읽는다.
따라서 논리적 I/O 횟수에는 물리적 I/O 횟수가 이미 포함되어 있다.
LRU 알고리즘
DBMS 는 사용 빈도가 높은 데이터 블록들이 버퍼캐시에 오래 남아있도록 하기 위해 LRU 알고리즘을 사용한다. 모든 버퍼 블록 헤더를 LRU 체인에 연결해서 사용빈도에 따라 수시로 위치를 옮기다가, FREE 버퍼가 필요해질 때면 액세스 빈도가 낮은 데이터 블록들을 우선하여 밀어낸다. 그러면 자주 액세스되는 블록들이 캐시에 오래 남게 된다.
이해를 돕기 위해, 입었던 옷을 항상 옷장 맨 우측에 건다고 생각해보자.
- 우측 (MRU END) 에는 자주 입는 옷들이 걸리고
- 좌측 (LRU END) 에는 잘 안 입는 옷들이 걸리게 된다. 새 옷을 사서 옷장 공간이 부족해지면 맨 좌측에 걸린 옷을 서랍으로 옮기면 된다.
LRU는 가장 오래 전에 마지막으로 사용했던 데이터 블록 (=페이지) 를 버퍼캐시에서 밀어내는 알고리즘이다.
반대로 MRU 는 가장 최근에 사용한 데이터블록 (=페이지) 를 버퍼캐시에서 밀어내는 알고리즘이다.
O
Direct Path I/O
Direct Path I/O는 데이터베이스의 버퍼 캐시(Buffer Cache)를 거치지 않고, 프로세스가 디스크와 메모리(PGA) 사이에서 데이터를 직접 주고받는 I/O 방식이다.
일반적인 I/O(Buffered I/O)가 모든 데이터를 SGA의 버퍼 캐시에 올린 후 읽는 것과 대조되는 개념이다.
1. 작동 원리 비교
-
일반 I/O (Buffered I/O): 디스크 → SGA 버퍼 캐시 → 프로세스(PGA). 데이터를 캐싱하여 재사용성을 높이지만, 대량의 데이터를 읽을 때는 캐시를 밀어내는(Aging out) 부하와 래치(Latch) 경합을 유발한다.
-
Direct Path I/O: 디스크 ↔ 프로세스 메모리(PGA). 버퍼 캐시를 완전히 우회한다. 따라서 버퍼 캐시 점유로 인한 다른 세션의 성능 저하를 방지하고, 대용량 처리에 특화된 성능을 보여준다.
2. 발생하는 주요 상황
오라클은 다음과 같은 특수한 경우에 Direct Path I/O를 수행한다.
-
Direct Path Read:
-
Parallel Query: 병렬 쿼리 실행 시 각 슬레이브 프로세스는 데이터를 직접 읽는다.
-
대용량 Full Table Scan: 테이블 크기가 버퍼 캐시보다 훨씬 클 경우, 오라클은 효율성을 위해 자동으로 Direct Path Read를 선택할 수 있다.
-
정렬 작업 (Sort):
SORT_AREA_SIZE를 초과하는 대량 정렬 시 임시 세그먼트(Temp)에서 읽어올 때 발생한다.
-
-
Direct Path Write:
-
Direct Path Insert:
/*+ APPEND */힌트를 사용한 데이터 입력. -
CTAS / IAS:
CREATE TABLE AS SELECT또는INSERT ... SELECT문 수행 시. -
정렬 작업: 정렬 중간 결과를 임시 세그먼트에 쓸 때 발생한다.
-
3. 장점과 단점
장점
-
버퍼 캐시 경합 제거:
CBC Latch나Buffer Busy Waits같은 메모리 경합 이벤트가 발생하지 않는다. -
대용량 처리 속도: CPU가 버퍼 캐시를 관리하는 오버헤드가 없으므로 대량의 Sequential I/O 시 속도가 매우 빠르다.
-
메모리 효율: 자주 쓰이는 작은 데이터를 보관해야 할 버퍼 캐시 공간을 대량의 스캔 데이터가 오염(Pollution)시키는 것을 막는다.
단점 및 제약
-
데이터 일관성 유지 비용: 쓰기 작업 시 해당 세그먼트에 대해 Exclusive Lock이 걸리거나, 읽기 작업 전 dirty block을 디스크에 기록해야 하는 Checkpoint 부하가 발생한다.
-
재사용 불가: 버퍼 캐시에 데이터가 없으므로, 동일한 데이터를 다시 읽을 때 무조건 다시 디스크 I/O를 수행해야 한다.
4. 관련 대기 이벤트
AWR 리포트나 세션 모니터링 시 다음 이벤트가 보인다면 Direct Path I/O가 활발히 일어나고 있는 것이다.
-
direct path read -
direct path write -
direct path read temp(정렬 관련) -
direct path write temp(정렬 관련)
요약
Direct Path I/O는 **“메모리(SGA) 관리 부담을 버리고, 디스크와 직접 소통하여 대량의 데이터를 빠르게 밀어내는 고속도로”**와 같다. OLTP 환경보다는 대규모 배치나 DW 환경에서 핵심적인 메커니즘이다.