아래는 sql trace report에서 Call 통계(Statistic)부분만을 발췌한 것이다. 이 레포트는 커서의 활동상태를 Parse, Execute, Fetch 세 단계로 나누어 각각에 대한 수행통계를 보여준다.
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.01 0.00 80 59 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.01 0.00 80 59 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Execute Call 시점에 모든 처리과정을 서버내에서 완료하고 처리결과만 리턴하므로 Fetch Call이 전혀 발생하지 않는다.
delete
from big_table
where rownum = 1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 61 0 0
Execute 1 0.00 0.00 0 4 3 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 65 3 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 41
Rows Row Source Operation
------- ---------------------------------------------------
1 DELETE BIG_TABLE (cr=4 pr=0 pw=0 time=114 us)
1 COUNT STOPKEY (cr=4 pr=0 pw=0 time=34 us)
1 TABLE ACCESS FULL BIG_TABLE (cr=4 pr=0 pw=0 time=30 us)
클라이언트로부터 명시적인 Fatch Call을 받지 않으며 서버 내에서 묵시적으로 Fatch가 이루어진다.
의문.: CATS도 마찬가지 일까? 나는 CATS로 테스트함. 맞는거는 같은데... 정확히 답좀 해주세요..
create table big_table as
select *
from all_tables
where rownum <= 10000
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.18 0.22 0 0 0 0
Execute 1 0.43 0.63 24 7659 401 2759
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.61 0.86 24 7659 401 2759
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Excetue Call 단계에서는 커서만 오픈하고, 실제 데이터를 처리하는 과정은 모두 Fatch 단계에서 일어난다.
예를들어, sort group by는 Execute 단계에서 처리할 것으로 예상되지만 실제로는 Fetch 시점에 처리가 일어난다. 실제 데이터를 액세스하면서 일을 시작하는 시점은 첫 번째 Fetch Call 인 것을 짐작할 수 있다.
select owner, count(*)
from big_table
group by owner
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 1 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.01 0.00 0 88 0 18
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.01 0.00 0 89 0 18
Execute Call 단계에서 모든 레코드를 읽어 Lock을 설정한다.
-- 내가 돌린쿼리
select *
from big_table for update
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.02 0.00 0 1 0 0
Execute 1 0.03 0.03 4 88 2811 0
Fetch 28 0.03 0.02 0 115 0 2759
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 30 0.08 0.06 4 204 2811 2759
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 41
Rows Row Source Operation
------- ---------------------------------------------------
2759 FOR UPDATE (cr=203 pr=4 pw=0 time=42812 us)
5518 TABLE ACCESS FULL BIG_TABLE (cr=203 pr=4 pw=0 time=5646 us)
-- 책의 결과
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.02 0.00 0 1 0 0
Execute 1 0.03 0.03 4 88 10178 0
Fetch 11 0.03 0.02 0 115 0 101
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 13 0.08 0.06 4 204 10178 101
-- 내가 100건만 돌린 결과
select *
from big_table
where rownum <= 100
for update
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.02 0 120 0 0
Execute 1 0.00 0.00 0 7 104 0
Fetch 2 0.01 0.00 0 7 0 100
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.01 0.03 0 134 104 100
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 41
Rows Row Source Operation
------- ---------------------------------------------------
100 FOR UPDATE (cr=14 pr=0 pw=0 time=1688 us)
200 COUNT STOPKEY (cr=14 pr=0 pw=0 time=490 us)
200 TABLE ACCESS FULL BIG_TABLE (cr=14 pr=0 pw=0 time=285 us)
책에서는 10,000건의 레코드가 있는 테이블을 for update 구문을 사용하여 실행시켰을때, Fetch단계에서는 101개의 레코드만 Fetch하고 멈추었지만, Execute 단계에서 이미 Current모드로 읽어 10,000개 레코드 전체에 대해 Lock을 설정했다고 되어있다.
의문: Execute 단계에서 이미 Current모드로 읽어 10,000개 레코드 전체에 대해 Lock을 설정했다는 건 이해가 가는데... Fecth 101건만 읽은 이유는 무었일까? for update단계에서 무슨일이 일어난걸까... 내가 테스트한 거에서는 저런 내용이 안나옴.... 나혼자만 실행해서 그런거일거라 생각은 듬...