session_cached_cursor:这个参数限制了在pga内session cursor cache list的长度,session cursor cache list(会话游标缓存链表)是一条双向的lru链表,当一个session打算关闭一个cursor时,如果这个cursor的parse count超过3次,那么这个cursor将会被加到session cursor cache list的MRU端.当一个session打算parse一个sql时,它会先去pga内搜索session cursor cache list,如果找到那么会把这个cursor脱离list,然后当关闭的时候再把这个cursor加到MRU端.session_cached_cursor提供了快速软分析的功能,提供了比soft parse更高的性能.
下面做个实验来证明以上这些理论
SQL> select distinct(sid) from v$mystat;
SID
----------
146
SQL> show parameter session_cached_cursors
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
session_cached_cursors integer 50
我们来把session_cached_cursors修改成1
SQL> alter session setsession_cached_cursors=1;
Sessionaltered.
这是设置session_cached_cursors为0,禁止了cachecursor的功能
我们另开一个sqlplus来看v$open_cursor
SQL> select * from v$open_cursor where sid=146;
能在v$open_cursor里看到这条sql
执行下一条语句
SQL> create table test as select * from dba_objects;
Table created.
SQL> select owner from test where rownum=1;
OWNER
------------------------------
SYS
在来看v$open_cursor有什么变化
可以看到语句变了,来看看current open cursor(当前打开游标)和session cached cursor(会话缓存游标数)的数目
SQL> selectsid,n.name,s.value used from
sys.v_$statname n,
sys.v_$sesstat s
where
n.name in('opened cursors current', 'session cursor cache count') and
s.statistic# = n.statistic#
andsid=146;
可以发现,当前打开的游标数量是1个,当前缓存的游标数量是0个。
再执行上面的语句
SQL> select owner from test where rownum=1;
OWNER
------------------------------
SYS
看看v$open_cursor
SQL> select * from v$open_cursor where sid=146;
此处执行3次 select* from v$open_cursor where sid=146,oracle进行了3次soft parse
SQL> select owner fromtest where rownum=1;
OWNER
------------------------------
SYS
SQL>select owner from test where rownum=1;
OWNER
------------------------------
SYS
然后再执行
SQL>select distinct sid from v$mystat;
SID
----------
146
再来看看v$open_cursor有什么变化
v$open_cursor有了两条记录,再看一下currentopen cursor和sessioncached cursor的数目
SQL> select sid,n.name,s.value used
from
sys.v_$statname n,
sys.v_$sesstat s
where
n.name in ('opened cursors current', 'session cursor cache count') and
s.statistic# = n.statistic#
and sid=146;
果然有一句sql进了session cursor cache,"select ownerfrom test where rownum=1"这个sql相关的cursor就被cache起来了.
再执行一条新的语句
SQL> select owner from test where rownum<2;
OWNER
------------------------------
SYS
看一下v$open_cursor
SQL> select * from v$open_cursor where sid=146;
可以看到上一次的"selectdistinct sid from v$mystat"已经被关闭,在v$open_cursor中不可见,但是cached cursor "select owner from test where rownum=1"还能看到
这时候运行3次select distinct sid from v$mystat
SQL>select distinct sid from v$mystat;
SID
----------
146
SQL>select distinct sid from v$mystat;
SID
----------
146
SQL>select distinct sid from v$mystat;
SID
----------
146
然后再运行selectowner from test where rownum<2
SQL> select owner from test where rownum<2;
OWNER
------------------------------
SYS
再去查看v$open_cursor
SQL> select * from v$open_cursor where sid=146;
发现原来cached cursor"select owner from testwhere rownum=1"已经被替换出了session cursor cache,而变成了"select distinct sid fromv$mystat"
我们再修改session_cached_cursors
alter session set session_cached_cursors=2;
再重复一下上面的过程,
再去看v$open_cursor
SQL>/
可以看到现在有3个cursor,看一下current open cursor和session cached cursor的数目
SQL> selectsid,n.name,s.value used
2 from
3 sys.v_$statname n,
4 sys.v_$sesstat s
5 where
6 n.name in ('opened cursors current', 'session cursor cachecount') and
7 s.statistic# = n.statistic#
8 and sid=146;
这下有2个cachedcursor,一个currentopen cursor.
从这个实验我们可以清楚得看到v$open_cursor视图和session_cached_cursors参数的作用.