Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
direct path read 24 0.00 0.00
SQL*Net message from client 2 11.13 11.13
********************************************************************************
direct path read : DBC 를 거치지 않고 커서에서 바로 읽기
풀 테이블 스캔시에 DBC 를 건드리는 행위 자체가 성능상에 문제를 일으킬 수 있으므로
한 번 I/O 콜이 발생할 때마다 24번 올렸다는 뜻
★ 시리얼 다이렉트 리드 Serial direct read
- 테이블이나 인덱스에 대한 풀 스캔이 발생할 경우 멀티 블록 I/O 가 발생하는데
이때 DBC 영역에 부담이 갈 수 있다.
- 디스크에서 데이터파일 블록을 메모리로 읽어오려면 래치를 잡아야 하는데
래치를 잡지 못하면 : cache buffers lru chain 대기이벤트가 발생한다.
- 래치를 잡고 LRU 리스트의 cold 영역 끝 부분에 블록을 읽어들이는데
그러면 그곳에 있던 블록들이 aging out 될 수 있다.
- 그런데 에이징아웃된 블록이 다른 세션에서 필요할 때는 다시 물리적인 I/O 가 또 발생할 수 있다.
- 그래서 풀 테이블 스캔이 발생하는 테이블의 블록들을 데이터 버퍼 캐시에 올리지 말고
서버 프로세스 안에 있는 PGA 안 커서에 데이터파일에서 바로 읽어오려는 기능
- 원래 direct read 방식은 병렬 parallel 처리시에 발생하는 기능인데
11g 부터는 병렬처리 힌트를 쓰지 않았더라도 direct read 방식이 구현된다.
SELECT a.ksppinm Parameter, b.ksppstvl Session_Value, c.ksppstvl Instance_Value
FROM x$ksppi a, x$ksppcv b, x$ksppsv c
WHERE a.indx = b.indx
and a.indx = c.indx
and a.ksppinm in ('_small_table_threshold', '_serial_direct_read');
히든 파라미터
_small_table_threshold : 풀테이블 스캔이 발생한다고 해서 무조건 direct path 방식으로 가는 것이 아님
633은 기준치, 풀테이블 스캔이 발생했을 경우 다이렉트 패스를 쓸 수 있는 경우는
633보다 블록 수가 많은 경우 (커서에 바로 읽어들임)
이것보다 블록이 작은 경우는 그냥 DBC 맨 끝쪽에 올린다.
HR@ora11g> exec dbms_application_info.set_client_info('sess_1')
PL/SQL procedure successfully completed.
HR@ora11g> select count(*) from ind_random where owner = 'SYS';
COUNT(*)
----------
29856
SYS@ora11g> select client_info, sid from v$session where client_info = 'sess_1';
SID 값 찾기
CLIENT_INFO SID
---------------------------------------------------------------- ----------
sess_1 191
SYS@ora11g> select sid, event, total_waits, time_waited from v$session_event where sid = 191;
191 세션 접속 이후의 대기이벤트 보기
SID EVENT TOTAL_WAITS TIME_WAITED
---------- --------------------------------------------------------------------------- -----------
191 Disk file operations I/O 2 0 --- 일반적으로 뜨는 대기이벤트
191 db file sequential read 18 12 --- 싱글 블록 I/O 발생 18번
191 direct path read 22 10 --- 다이렉트 패스 리드 방식 22번
SID EVENT TOTAL_WAITS TIME_WAITED
---------- --------------------------------------------------------------------------- -----------
191 SQL*Net message to client 16 0
191 SQL*Net message from client 15 19650
191 SQL*Net break/reset to client 2 0
6 rows selected.
풀 테이블 스캔밖에 안했는데 왜 db file sequential read 가 18번이나 뜰까?
A | B | |
C |
A | |||||||
B | |||||||
C |
디스크에서 블록을 올리려고 하는데 > 군데군데 이미 메모리에 있는 블록들이 있다
이럴 때 싱글 블록 I/O 와 멀티 블록 I/O가 번갈아서 일어난다.
그래서 스캔 성능을 좋게 하려면 flush 하는 것도 좋은 방법(?) 이다.
SYS@ora11g> alter system flush buffer_cache;
System altered.
SYS@ora11g> /
System altered.
<<hr 로 다시 접속하기>>
HR@ora11g> exec dbms_application_info.set_client_info('sess_1')
PL/SQL procedure successfully completed.
SYS@ora11g> select client_info, sid from v$session where client_info = 'sess_1';
CLIENT_INFO SID
---------------------------------------------------------------- ----------
sess_1 9
SYS@ora11g> select sid, event, total_waits, time_waited from v$session_event where sid = 9;
SID EVENT TOTAL_WAITS TIME_WAITED
------------------------------------------------------------------------------------------------
9 Disk file operations I/O 2 0
9 db file sequential read 7 6
9 direct path read 22 0
SID EVENT TOTAL_WAITS TIME_WAITED
------------------------------------------------------------------------------------------------
9 SQL*Net message to client 14 0
9 SQL*Net message from client 13 1513
2024년 2월 14일 3교시 (0) | 2024.02.14 |
---|---|
2024년 2월 14일 2교시 (0) | 2024.02.14 |
2024년 2월 8일 1교시 (0) | 2024.02.08 |
2024년 2월 7일 5교시 (0) | 2024.02.07 |
2024년 2월 7일 4교시 (0) | 2024.02.07 |