暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle库 缓冲区命中率低问题的解决

东面而视 2018-08-09
1324

库缓存中主要存储了: 
1,sql语句及其执行计划 
2,pl/sql及编译结果:过程,函数,程序包,触发器,匿名块。

库缓冲区命中率 应至少在95%以上,如果低于95%那么首先要确定

1,确定命中率: 
select round((sum(pinhits) / sum(pins)) * 100 ,2) || ‘%’ lhitratio 
from vlibrarycachewhere(pinhits>0andpins>0);2,sharepoolsize300mselectvalue/1024/1024sharedsizefromvlibrarycachewhere(pinhits>0andpins>0);2,sharepoolsize300mselectvalue/1024/1024sharedsizefromvparameter where name=’shared_pool_size’; 
3,看是否有空闲空间 
select bytes/1024/1024 freemb from vsgastatswheres.pool=sharedpoolands.name=freememory;4,selectround((sum(reloads)/sum(pins))100,2)||fromvsgastatswheres.pool=sharedpoolands.name=freememory;4,selectround((sum(reloads)/sum(pins))100,2)||fromvlibrarycache where (pinhits>0 and pins>0); 
这个值要在1以内,这个就是sql被重新加载的次数,一般情况下我们只加载一次就够了,下次就直接从库缓存中直接读取,但有的时候需要重新加载,比如:表被分析,表被truncate,drop等,pl/sql被重新编译等。

还是要强调那句话,一味的增加大小不会解决质的问题,过大的shared_pool还会增加oracle的管理开销。 
我们应该从sql语句中去找寻问题,如果库缓冲区命中率低的话,我遇到过一种情况(大多数都是这样):绑定变量。 
那我们怎么定位是否绑定变量呢 
通过2个视图我们基本可以确定: 
1,v$sqlarea视图

select count() ,PERSISTENT_MEM from v$sqlarea group by PERSISTENT_MEM having count()>10 order by count(*) desc;

COUNT(*) PERSISTENT_MEM


 2730           1808
 1444           1856
  337            904
  • 1

  • 2

  • 3

  • 4

count(*)是求的sql数量 
PERSISTENT_MEM :是占有稳定的内存数

persistent_mem 凡是我们因为没有绑定变量,sql语句一样只是where条件的值不一样,那么他的persistent_mem一定是一样的 
这样我们就可以通过这个值的大小,和出现次数来判断有多少sql运行这个值是一样的,如果过多那么基本可以判断重复的sql过多,没有绑定变量。

我们可以select sql_text from v$sqlarea where PERSISTENT_MEM=1808;来看是否有许多重复,没有绑定变量运行的sql语句。

2,v$db_object_cache视图

SELECT owner, name, kept, loads 
FROM V$DB_OBJECT_CACHE 
WHERE loads >1 and owner= ‘用户名’ 
ORDER BY loads DESC;

OWNER NAME KEPT LOADS 
———- ———————————– ——— ————– 
DC QUOTATION NO 1623 
DC RATOR NO 1545 
DC N_PARAS NO 1535 
DC RAGE_REAL_COST NO 1418 
SD D_DETAIL NO 1405 
SD TEMPARAMETER NO 1399 
LDC T_ENTRUST NO 1365 
LDP TRACTSTATE NO 1293 
LDP N_PARAS NO 1289 
LDC VARIETY NO 1200 
LDP RATOR NO 1181

可以看到 许多对象(表)被反复loads的次数很大,在v$db_object_cache表里被反复load多数是因为缓存不够,被挤出。而造成这种原因多数是因为没有绑定变量,大量重复加载一样的语句造成的。而通过增加share_pool不能解决根本问题

解决方法: 
1,修改sql语句,改用变量代替常量(开发来完成) 
2,可以keep一些经常用到的小表。dbms_shared_pool数据包,可以通过loads的次数和表的大小综合考虑要keep那些表(DBA来完成)



文章转载自东面而视,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论