17. 调整共享池保留空间
/诊断工具 V$shared_pool_reserved
--在一个有足够空闲内存的系统,调整的目标是 request_misses=0
/通过dbms_shared_pool_pachage.aborted_request_threshold过程来设置一个阀值
比如有个包在reserver中请求2M空间,reserver会去找一个2M的连续空间出来,一般情况下,如果没有则会请出一些对象以获得这2M内存,但是你可以设置一个阀值比2M小一点,那么不管有没有2M或者以上的空闲内存,就都不会让2M及其以上的对象进来
/设置初始化参数shared_pool_reserved_size
---当shared_pool_reserved_size太小,可以适当增大他的大小
--当他太大,以下任何一种情况满足应该适当减小shared_pool_reserved_size的值
/request_miss=0或者保持一个值而不再增大是,可以减小shared_pool_reserved_size到一个适合这个情况的最小值,
释放出不必要的内存给其他的人用
/shared_pool_reserved中如果Free_space 大于其50%时
/shared_pool_size太小时
使用V$shared_pool_reserved也可以诊断出shared_pool_size太小,这是request_failuer>0并且持续增大的一个原因,这个时候,如果
你已经启用了the reserved list,那么减小shared_pool_reserved_size的大小,如果没有,则要增加shared_pool_size的大小。
18. 在共享池中栓住大对象
/调查库缓存中那些大对象没有被栓住, 比如大于1万字节的
select * from v$db_object_cache where shareable_mem>10000
and kept='NO' [and type in ('PACKAGE', 'PACKAGE BODY', 'FUNCTION','PROCEDURE')]
/用什么工具来栓住他们到共享池中,用dbms_shared_pool.keep(package_nem)这个包过程
现在我们应该知道为什么要栓住这些大对象吧,如果不栓住这些大对象,在加载到库池时极容易引起内存碎片,为了能够获得足够的连续空间,甚至需要将大量的小对象从共享池中赶出去,这样将会导致命中率低,响应用户的时间增加,对不对啊!为了避免这种糟糕的情况发生,我们就有必要以启动instance,就先栓住这些常用的大对象,这样他们可以一直保存在内存中,也不再去和那些小对象去抢空间了。
/那些对象应该被栓住
--经常需要的大的存储过程,比如standard包,diutil包以及那些超过定义的阀值的常用的大对象
--使用频率很高的那些表对应的触发器
--序列sequence, 缓存起来可以增加响应的速度,(创建sequence有一个cache N从句,可以一次生成多少个值缓存起来)
/什么时候栓住他们最好
在前面我已经提到过好几次了,大家想起来了没有。在instance一起来就把他们栓住。
/凡是被栓住的对象,即使你执行alter system flush shared_pool;时也不会被赶出去,还在里面,是不是很有好处啊?
19. 匿名PL/SQL块
/怎样找出匿名块,找到后该怎么优化
--查询视图v$sqlarea中command_type=47的SQL,这个就是匿名块,比如
select sql_text from v$sqlarea where Command_type=47 and length(sql_text)>500
--一般来说找到他们后尽可能的把他们转换成小的包函数,但是如果不能转化又怎么办,那就把他们栓住啊,
比如,步骤如下:
1) declare x number declare /* KEEP_ME */ x number
begin x:=5 -------------> begin x:=5;
end; end;
2) select address, hash_value from v$sqlarea where command_type=47 and sql_text like '%KEEP_ME%';
3) execute dbms_shared_pool_keep('address,hash_value');这里'address,hash_value'是上面查出来的值啊
20. 影响库缓存的其他一些参数
/open_cursors 50(default)|n
这个参数定义了在用户进程的私有(不共享)SQL区域最多能打开的游标数量,对于中型应用一般设为300
/Cursor_space_for_time false(default)|true
表示是否缓存cursor, true能够提高命中率,但增加负荷,慎重,那什么时候可以改为true呢?
因为设置为true, 你是那空间来换时间,如果你有足够的内存,能使V$librarycache中reloads等于0或者趋近0的时候,你当然可以设置为true.
如果你的应用使用了oracle forms和任何动态SQL, oracle建议保留默认值false
/session_cached_cursors 0(default,不缓存)
如果应用程序是form型的,将这个值设为true,可以改进库缓存的命中率,因为窗体中所包含的SQL语句将被缓存,当窗体来回切换时可以减少重分析的次数。
/Cursor_sharing exact|similar|force
这个前面已经详细介绍过,这里不再介绍了,大家如果不清楚可以翻看前面。
21. 调整数据词典缓存
前面我们一直在讨论的是库缓存,大家知道,共享池中还有一个很重要的组件,那就是数据词典缓存。这讲开始我们开始讨论这个问题。
/存放的内容:数据对象的定义
/使用v$rowcache视图可以得到数据词典缓存中的信息,主要有了解三个列
--paramter: 缓存中数据词典的名称
--gets: 请求的总次数
--getmisses: 请求时没有在缓存中找到的次数,丢失
/优化目标:避免丢失,提高命中率, 丢失率:getmisses/gets
/要调整数据词典缓存大小,只能通过改变shared_pool_size参数来调整
/在实例刚起来的时候,由于数据词典缓存中没有数据,所以任何执行的SQL第一次都需要从磁盘文件加载数据词典,产生缓冲丢失。但是,随着数据库稳定持续的运行,常用的数据词典对象就应该缓存到了内存中,在这个时候,缓存丢失发生的几率就应该很小。为了调优数据词典缓存,应该实在应用已经稳定持续运行了一段时间,而不是instance启动的时候。

