2.如果PIN对象
(1)、PIN住SQL语句
第一步查出SQL语句在库缓存中的地址和SQL语句的HASH值:
SQL> select substr(sql_text,1,40) sqlt, address, hash_value from v$sql where sql_text = 'select name from ui1 where id=101';
SQLT ADDRESS HASH_VALUE
---------------------------------------- -------- ----------
select name from ui1 where id=101 2345C39C 2874596039
第二步调用DMBS_SHARED_POOL.KEEP过程PIN住对象:
先来看看文档中此过程的定义:
DBMS_SHARED_POOL.KEEP (
name VARCHAR2,
flag CHAR DEFAULT 'P');
它有两个参数,第一个参数是要PIN在内存中的对象的名字,也可以对象的地址、HASH值组成的字符串。对于上面的游标对象,必须使用地址、HASH值字符串,使用形式为:‘2345C39C,287459603’。也就是‘Address,hash_value’。
第二个参数,说明被PIN的对象的类型。有如下几种类型:
'P' or 'p' :被PIN对象是包、过程或函数,这个是缺省值
'T' or 't' :被PIN对象是TYPE。它类似C语句中的结构,是开发中常用的组合型数据。
'R' or 'r' :被PIN对象是触发器
'Q' or 'q' :被PIN对象是序列
如果是游标对象,可以随变指定一个非上面列出的字母,我一般常用C,它是Cursor的第一个字母。另外,表、索引还有视图不能被PIN到内存中。好,下面调用此过程将上面例子中的游标PIN到内存中:
SQL> exec dbms_shared_pool.keep('2345C39C,2874596039','c');
PL/SQL 过程已成功完成。
被PIN住的对象,我们可以使用UNKEEP过程取消PIN,调用方法非常简单:
SQL> exec dbms_shared_pool.unkeep('2345C39C,2874596039','c');
PL/SQL 过程已成功完成。
(注意,此处不必讲述,被PIN的游标对象,只有父子对象的句柄还有父对象的0号子堆内存将会一直保留,其他子堆仍会老化。这个可以通过Alter system flush shared_pool查看,刷新共享池后,只有对象句柄和父对象0号子堆还有共享池中。对于过程,在刷新共享池后,将保留句柄和堆0的内存,其他内存也会被清掉)
-