
library cache : SQL 실행에 관련된 모든 객체에 대한 정보 관리
data dictionary cache : 딕셔너리 정보들이 저장되어 있는 메모리
session, process, enqueue, transaction 정보
shared server 환경일 경우 UGA(User Global Area)가 포함될 수 있다.
예) select * from hr.employees where employee_id = 100;
예) 'select * from hr.employees where employee_id = 100'; -- 잘못되었다 예
'select * from hr.employees where %'; -- 런타임시점까지 where 절의 조건을 모른다.
런타임에서 사용자의 입력값에 따라 동적으로 SQL 구문을 생성하여 실행하는 방식의 SQL문이다.
동적으로 처리하기 위해 문자열 변수를 활용하여 런타임시 구문이 확정된다는 특징을 가지고 있다.
수행할때마다 컴파일 해야하기 때문에 하드파싱이 발생된다.
plsql 안에서 DDL문을 사용하기 위해서는 dynamic sql(execute immediate문)을 사용해야 한다.
runtime 시점까지 where 절의 어떤 컬럼을 사용해서 조건을 줄지 모르면 dynamic sql을 사용하고 어떤 컬럼을 사용해서 where 조건을 줄지 알면 static sql을 사용한다.
execute dbms_application_info.set_client_info('sess_1')
declare
v_cnt number;
begin
for i in 1..10000 loop
execute immediate 'select /* example */ count(*) from dual where dummy=to_char('||i||')' into v_cnt;
end loop;
end;
/
execute dbms_application_info.set_client_info('sess_2')
declare
v_cnt number;
begin
for i in 1..10000 loop
execute immediate 'select /* example */ count(*) from dual where dummy=to_char('||i||')' into v_cnt;
end loop;
end;
/
select client_info, sid from v$session where client_info in ('sess_1','sess_2');
select sql_id, sql_text, parse_calls, loads, executions,invalidations
from v$sql
where sql_text like '%example%'
and sql_text not like '%v$sql%';

select sid, event, total_waits, time_waited/100
from v$session_event
where sid in (55,277);

latch shared pool wait event가 발생하는걸 확인할 수있다. cursor : pin S wait on X : library cache pin을 shared 모드로 갖고 싶은데 다른 세션에서 exclusive 모드로 가지고 있어 기다리는 상황select sql_id, sql_text, parse_calls, loads, executions,hash_value, plan_hash_value
from v$sql
where sql_text like '%example%'
and sql_text not like '%v$sql%';

execute dbms_application_info.set_client_info('sess_1')
declare
v_cnt number;
begin
for i in 1..10000 loop
execute immediate 'select /* example */ count(*) from dual where dummy=to_char(:b)' into v_cnt using i;
end loop;
end;
/
execute dbms_application_info.set_client_info('sess_2')
declare
v_cnt number;
begin
for i in 1..10000 loop
execute immediate 'select /* example */ count(*) from dual where dummy=to_char(:b)' into v_cnt using i;
end loop;
end;
/
select client_info, sid from v$session where client_info in ('sess_1','sess_2');
select sql_id, sql_text, parse_calls, loads, executions,invalidations
from v$sql
where sql_text like '%example%'
and sql_text not like '%v$sql%';

plsql을 사용하면 반복되는 sql문을 실행할때마다 latch(mutex)를 잡을 필요 없이 바로 LCO로 접근할 수 있는 캐시 기능을 제공하기 때문에 두번째 접근부터는 바로 latch 잡지않고 LCO로 이동해서 parse는 더이상 증가되지 않고 execution만 증가하게 된다.
-execution은 증가하는 이유는 dynamic sql문은 프로그램과 분리된다.
프로그램안에 dynamic sql문을 사용한 경우 shared pool 안에 sql area와 plsql area에 LCO가 만들어진다.
select sid, event, total_waits, time_waited/100
from v$session_event
where sid in (55,277);

execute dbms_application_info.set_client_info('sess_1')
declare
v_cnt number;
begin
for i in 1..10000 loop
select /* example */ count(*)
into v_cnt
from dual
where dummy=to_char(i) ;
end loop;
end;
/
execute dbms_application_info.set_client_info('sess_2')
declare
v_cnt number;
begin
for i in 1..10000 loop
select /* example */ count(*)
into v_cnt
from dual
where dummy=to_char(i);
end loop;
end;
/
select client_info, sid from v$session where client_info in ('sess_1','sess_2');
select sql_id, sql_text, parse_calls, loads, executions,invalidations
from v$sql
where sql_text like '%example%'
and sql_text not like '%v$sql%';

프로그램(프로시저,함수,패키지) 안에서는 static sql문은 일체형이다. latch의 캐시기능으로 같은 SQL문장의 경우 두번째 경우부터 바로 해당 LCO로 이동하기 때문에 parse 와 execution이 증가하지 않는다.
프로그램 안에 static sql문으로 작성했을 경우 shared pool 안에 plsql area공간에만 LCO가 만들어진다.
select sid, event, total_waits, time_waited/100
from v$session_event
where sid in (55,277);

show parameter session_cached_cursors

_kghdsidx_count의 값만큼 서브풀을 생성해서 관리한다.select name, gets from v$latch_children where name='shared pool';
NAME GETS
--------------------------------------------- ----------
shared pool 35
shared pool 35
shared pool 35
shared pool 35
shared pool 35
shared pool 35
shared pool 2892659 <- 사용하고 있는 latch
7 rows selected.
select a.ksppinm as parameter,b.ksppstvl as session_value, c.ksppstvl as 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 = '_kghdsidx_count';

- 현재 cpu 갯수 확인
show parameter cpu_count

desc v$sql_shared_cursor variable name varchar2(10)
exec :name := 'King'
SYS@ORA19C> print name
NAME
---------------------------------------------
King
SYS@ORA19C> select last_name, salary from hr.employees where last_name = :name;
LAST_NAME SALARY
------------------------- ----------
King 10000
King 24000
variable name varchar2(1000)
exec :name := 'Grant'
SYS@ORA19C> print name
NAME
---------------------------------------------
Grant
SYS@ORA19C> select last_name, salary from hr.employees where last_name = :name;
LAST_NAME SALARY
------------------------- ----------
Grant 2600
Grant 7000
select sql_id, sql_text, version_count
from v$sqlarea
where sql_text like '%hr.employees%'
and sql_text not like '%v$sqlarea%';

- version count 이유 찾기
select address, child_address, child_number, bind_length_upgradeable from v$sql_shared_cursor where sql_id ='gqgwd5rvu5ftu';

- 실행계획 확인
select * from table(dbms_xplan.display_cursor('gqgwd5rvu5ftu',0));
select * from table(dbms_xplan.display_cursor('gqgwd5rvu5ftu',1));

- bind 변수의 대입값 확인
select address, child_address,datatype_string, max_length, value_string
from v$sql_bind_capture
where sql_id = 'gqgwd5rvu5ftu';

alter system flush shared_pool;
variable name varchar2(4000)
exec :name := 'King'
SYS@ORA19C> print name
NAME
---------------------------------------------
King
SYS@ORA19C> select last_name, salary from hr.employees where last_name = :name;
LAST_NAME SALARY
------------------------- ----------
King 10000
King 24000
variable name varchar2(10)
exec :name := 'Grant'
SYS@ORA19C> print name
NAME
---------------------------------------------
Grant
SYS@ORA19C> select last_name, salary from hr.employees where last_name = :name;
LAST_NAME SALARY
------------------------- ----------
Grant 2600
Grant 7000
select sql_id, sql_text, version_count
from v$sqlarea
where sql_text like '%hr.employees%'
and sql_text not like '%v$sqlarea%';

- bind 변수의 대입값 확인
select address, child_address,datatype_string, max_length, value_string
from v$sql_bind_capture
where sql_id = 'gqgwd5rvu5ftu';
