create or replace view stats
as select 'STAT...' || a.name name
,b.value
from v$statname a
,v$mystat b
where a.statistic# = b.statistic#
union all
select 'LATCH.' || name
,gets
from v$latch;
create global temporary table run_stats(
runid varchar2(15)
, name varchar2(80)
, value int
) on commit preserve rows;
create or replace package runstats_pkg
as
procedure rs_start; --Runstats가 시작되면서 호출된다.
procedure rs_middle; -- 예상대로 도중에 호출된다.
procedure rs_stop( p_difference_threshold in number default 0 ); -- 작업을 마치고 보고서를 인쇄한다.
end;
/
-- 실행의 경과 시간을 기록하는 데 사용되는 몇 가지 글로벌 변수로 시작
create or replace package body runstats_pkg
as
g_start number;
g_run1 number;
g_run2 number;
-- RS_START 루틴은 단순히 테이블을 차지하고 있는 통계를 지우고 "사용 전" 통계와 래치로 이 테이블을 채운다
-- 그런 다음 현재 시간 값(경과된 시간을 1/100초 단위로 계산하기 위하여 사용되는 정렬 시계)을 갈무리한다.
procedure rs_start
is
begin
delete from run_stats;
insert into run_stats
select 'before', stats.* from stats;
g_start := dbms_utility.get_time;
end;
-- RS_MIDDLE 루틴은 테스트의 첫 번째 실행에 대한 경과 시간을 G_RUN1에 기록한 후 현재의 통계 및 래치의 집합을 삽입
-- 이전에 RS_START에서 저장된 값에서 이들 값을 빼면 첫 번째 방법이 사용한 래치와 커서(통계)의 수 등을 알 수 있다.
procedure rs_middle
is
begin
g_run1 := (dbms_utility.get_time-g_start);
insert into run_stats
select 'after 1', stats.* from stats;
g_start := dbms_utility.get_time;
end;
-- RS_STOP 루틴은 다음 실행의 시작 시각을 기록한다.
procedure rs_stop(p_difference_threshold in number default 0)
is
begin
g_run2 := (dbms_utility.get_time-g_start);
dbms_output.put_line
( 'Run1 ran in ' || g_run1 || ' hsecs' );
dbms_output.put_line
( 'Run2 ran in ' || g_run2 || ' hsecs' );
dbms_output.put_line
( 'run 1 ran in ' || round(g_run1/g_run2*100,2) ||
'% of the time' );
dbms_output.put_line( chr(9) );
insert into run_stats
select 'after 2', stats.* from stats;
dbms_output.put_line
( rpad( 'Name', 30 ) || lpad( 'Run1', 12 ) ||
lpad( 'Run2', 12 ) || lpad( 'Diff', 12 ) );
for x in
( select rpad( a.name, 30 ) ||
to_char( b.value-a.value, '999,999,999' ) ||
to_char( c.value-b.value, '999,999,999' ) ||
to_char( ( (c.value-b.value)-(b.value-a.value)), '999,999,999' ) data
from run_stats a
,run_stats b
,run_stats c
where a.name = b.name
and b.name = c.name
and a.runid = 'before'
and b.runid = 'after 1'
and c.runid = 'after 2'
and (c.value-a.value) > 0
and abs( (c.value-b.value) - (b.value-a.value) )
> p_difference_threshold
order by abs( (c.value-b.value)-(b.value-a.value))
) loop
dbms_output.put_line( x.data );
end loop;
dbms_output.put_line( chr(9) );
dbms_output.put_line
( 'Run1 latches total versus runs -- difference and pct' );
dbms_output.put_line
( lpad( 'Run1', 10 ) || lpad( 'Run2', 10 ) ||
lpad( 'Diff', 10 ) || lpad( 'Pct', 8 ) );
for x in
( select to_char( run1, '9,999,999' ) ||
to_char( run2, '9,999,999' ) ||
to_char( diff, '9,999,999' ) ||
to_char( round( run1/run2*100,2 ), '999.99' ) || '%' data
from ( select sum(b.value-a.value) run1
,sum(c.value-b.value) run2
,sum( (c.value-b.value)-(b.value-a.value)) diff
from run_stats a
,run_stats b
,run_stats c
where a.name = b.name
and b.name = c.name
and a.runid = 'before'
and b.runid = 'after 1'
and c.runid = 'after 2'
and a.name like 'LATCH%'
)
) loop
dbms_output.put_line( x.data );
end loop;
end;
end;
/
create table t ( x varchar2(30) );
create or replace procedure method1( p_data in varchar2 )
is
begin
execute immediate
'insert into t(x) values(:x)'
using p_data;
end method1;
/
create or replace procedure method2( p_data in varchar2 )
is
begin
execute immediate
'insert into t(x) values( ''' || replace( p_data,'''','''''' ) || ''' )';
end method2;
/
set serveroutput on size 1000000;
-- dbms_output.put_line 확인
-- ORA-2000: buffer overflow, limit of 2000 bytes 오류 해결
begin
runstats_pkg.rs_start;
for i in 1 .. 10000
loop
method1( 'row ' || I );
end loop;
runstats_pkg.rs_middle;
for i in 1 .. 10000
loop
method2( 'row ' || I );
end loop;
runstats_pkg.rs_stop;
end;
/
method1 | mothod2 | 차이 | |
---|---|---|---|
래치 합계 | 365471 | 797749 | 432278 |
- 강좌 URL : http://www.gurubee.net/lecture/3453
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.