1、shared pool的组成
3块区域:free、library cache 缓存SQL语句及执行计划、row cache 字典对象的定义与权限信息缓存
(permanent area实例启动时固定分配,segmented arrays锁,事务等,library cache,row cache,reserved cache大对象保留池)
select * from v$sgastat a where a.NAME = 'library cache'; --11g已没有
select * from v$sgastat a where a.pool = 'shared pool' and a.NAME = 'free memory';
select * from v$sgastat a where a.NAME = 'row cache'; --dictionary cache
select * from v$sgastat; --shared pool各个子池的大小,名称,java pool,large pool也存在
大小参数:shared_pool_szie
数据字典:存储oracle自身信息的表或者视图
2、硬解析、软解析
硬解析步骤:语法,对象是否存在,用户是否有权限操作对象,生成执行计划,挑选最终执行计划(消耗大量资源占解析的70%)
软解析步骤:语法,对象是否存在,用户是否有权限操作对象
shared pool内存块组织结构
两个概念:chain(bucket)、chunk
free部分的chunk是按照大小挂在chain上的,当硬解析完一个sql及执行计划后,从free中取来一个大小相当的chunk存入,放
入library cache里,剩下的小chunk再链到小的chain上,解析时先到dictionary cache中去找与语句有关的数据,字典信息,比
如表 名、表的列等,以及用户权限等信息。硬解析需要使用free空间,同时产生小的chunk,所以会出现chunk数增多
library cache中的chunk也挂在chain上(按照chunk里缓存的SQL语句相关值),判断sql是否已缓存,是将新来的sql语句经过一
系列的运算(sql-ascii-hash-运算-chain值)得出liabrary chain里的相同编号的chain,再在该chain上根据sql语句的hash值找
到存储sql及执行计划的chunk,
跟踪解析过程中chunk的变化过程:
select count(*) from x$ksmsp; --chunk总数
select * from x$ksmsp; --每一个chunk都会有一条信息
连续执行,间隔时间里产生的chunk数量,确定是否硬解析及多少硬解析
alter system flush shared_pool; --清空library cache和row cache里的内容;
解析情况查询:
select name,value from v$sysstat where name like 'parse%'; --cpu消耗,总解析,硬解析,解析失败
3、SQL共享,sql完全相同,(每一个字母必须相同)
绑定变量
SQL语句组成,动态部分、静态部分
cursor_sharing: [FORCE | SIMILAR | EXACT]
FORCE 字面值强制绑定,无论是否最佳
SIMILAR 字面值强制绑定,同时选用最佳效率
EXACT 字面值严格完全相同判断
show parameter cursor;
alter system set cursor_sharing = exact scope = both;
declare
sql_text varchar2(2000);
n2 varchar2(20);
begin
for i in 1..100 loop
n2:='fhf'||i;
sql_text:='insert into t1(object_id,name) values (:1,:2)';
execute immediate sql_text using i,n2;
end loop;
commit;
end;
select /*hello*/ count(1) from t1 where object_id =1;
select /*hello*/ count(1) from t1 where object_id =2;
select /*hello*/ count(1) from t1 where object_id =1;
通过sql_id区分是否实现了sql共享
select sql_id,EXECUTIONS,HASH_VALUE,PLAN_HASH_VALUE,sql_text from v$sql where sql_text like '';
4、找出没有共享的SQL语句
在v$sql查找执行次数较小的sql语句,观察这些sql语句是否是经常执行的。
select SQL_FULLTEXT from v$sql where EXECUTIONS=1 and sql_text like '%from t%';
select SQL_FULLTEXT from v$sql where EXECUTIONS=1 order by sql_text;
5、解析命中率,软解析成功的次数>99.8%
select sum(pinhits)/sum(pins)*100 from v$librarycache; --99%接近100才好,数据库跑一段时间后查询
select sum(gets),sum(getmisses),100*sum(gets-getmisses)/sum(gets) from v$rowcache where gets>0;
6、解决4031错误的方法
查看4031错误,indx子池序号,kghlunfu各子池出现4031错误次数,kghlunfs最后一次出现时申请的大小(参照设置保留对象大小),
select indx, kghlurcr, kghlutrn, kghlufsh, kghluops, kghlunfu, kghlunfs from sys.x$kghlu
where inst_id = userenv('Instance');
ora-4031错误:free空间不够解析一个新的较大sql时发生,原因是共享池空间不足和碎片过多
1、alter system flush shared_pool; --清理碎片,碎片程度查看方法
2、共享SQL
alter system set cursor_sharing ='force';
3、强制缓存技术,手动缓存较大的SQL语句,不会被置换出来
select * from v$db_object_cache where sharable_mem > 10000
and (type = 'PACKAGE' or type='PACKAGE BODY' or type = 'FUNCTION' or type='PROCEDURE')
and kept = 'NO';
执行dbms_shared_pool.keep('对象名');
execute dbms_shared_pool.keep('DBMS_SQL');
@?/rdbms/admin/dbmspool.sql
4、保留区,达到保留区对象大小时自动缓存,专门缓存大对象
shared_pool_reserved_size:保留池大小,shared_pool_size的5%
_shared_pool_reserved_pct:指定保留池与shared_pool_size的比例,缺省5%
_shared_pool_reserved_min_alloc:缺省4400字节
调整大小:alter system set "_shared_pool_reserved_min_alloc"=4000 scope = spfile;
select * from x$ksppcv where indx in
(select indx from x$ksppi where ksppinm in
('_shared_pool_reserved_pct','_shared_pool_reserved_min_alloc'));
在保留区找不到空间
select * from v$shared_pool_reserved;
http://www.linuxidc.com/Linux/2012-05/59844.htm
5、增加shared pool空间
alter system set shared_pool_size=150M scope=both;
6、定期清理连接与实例重启
select COMPONENT,CURRENT_SIZE from V$SGA_DYNAMIC_COMPONENTS; #当前值
show parameter sga_target:动态参数,统一分配
show parameter sga_max_size:静态参数,防止动态修改的sga_target设置过大,先修改sga_max_size,重启
7、查看执行计划
select SQL_ID,sql_text,EXECUTIONS from v$sql where SQL_TEXT;
select * from table(dbms_xplan.display_cursor('bwhzpth8a3zgv'));--通过sqlid查看执行计划
8、在Oracle10g中允许有多个sub shared pool,可以设置大于1G的shared pool
没有实现sql共享时shared pool作用为反的;越大危害越大10g以前不超过1个G,10g后可以设大
共享池的子池(subpool)
利:减少共享池争用,提高访问的并发;弊:增加共享池碎片的机会
4个CPU1个subpool,最多7个
最小值:9i 128M 10g 256M 11g 512M
设置shared pool的大小
SELECT
shared_pool_size_for_estimate "SP_SIZE M",
estd_lc_size "EL",
estd_lc_memory_objects "ELM",
estd_lc_time_saved "ELT", estd_lc_time_saved_factor "parse factor",
estd_lc_memory_object_hits "ELMO"
FROM v$shared_pool_advice;
查询该设置大小
SELECT 'Shared Pool' component,
shared_pool_size_for_estimate estd_sp_size,--值得间隔为shared pool大小的10%为间隔
estd_lc_time_saved_factor parse_time_factor,
CASE
WHEN current_parse_time_elapsed_s + adjustment_s < 0
THEN 0
ELSE
current_parse_time_elapsed_s + adjustment_s
END response_time
FROM (SELECT shared_pool_size_for_estimate,shared_pool_size_factor,estd_lc_time_saved_factor,a.estd_lc_time_saved,
e.VALUE/100 current_parse_time_elapsed_s,c.estd_lc_time_saved - a.estd_lc_time_saved adjustment_s
FROM v$shared_pool_advice a,(SELECT * FROM v$sysstat WHERE NAME = 'parse time elapsed') e,
(SELECT estd_lc_time_saved FROM v$shared_pool_advice WHERE shared_pool_size_factor = 1) c);
9、补充内容
查询oracle数据块的大小 show parameter block
查询windows物理内存大小:systeminfo
查询linux物理内存大小:free -m 单位是M
10.共享池相关闩锁及优化
shared pool
library cache
library cache pin
row cache objects
row cache enqueue latch
11.SESSION_CACHED_CURSORS
定义一个session可以缓存多少个cursor,让后续相同的SQL语句不再打开游标,从而避免软解析的过程来提高性能。
oracle的session cursor cache是一块内存区域,用来存储关闭了的cursor,parse之前在这里找sql的缓存,会消耗内
存空间。
select name,value from v$sysstat where name like '%cursor%';
select name,value from v$sysstat where name like '%parse%';
根据session cursor cache hits/parse count(total)来调整SESSION_CACHED_CURSORS的大小;
软解析的指标:% Non-Parse CPU 解析外的时间即执行查询时间,如果很低说明解析次数多
12.共享池相关脚本
查询共享池内细分各类内存状态信息
SELECT KSMCHCLS CLASS, COUNT(KSMCHCLS) NUM, SUM(KSMCHSIZ) SIZ,
To_char( ((SUM(KSMCHSIZ)/COUNT(KSMCHCLS)/1024)),'999,999.00')||'k' "AVG SIZE"
FROM X$KSMSP GROUP BY KSMCHCLS;
查询共享池碎片化程度信息
select KSMCHIDX "SubPool", 'sga heap('||KSMCHIDX||',0)'sga_heap,ksmchcom ChunkComment,
decode(round(ksmchsiz/1000),0,'0-1K', 1,'1-2K', 2,'2-3K',3,'3-4K',
4,'4-5K',5,'5-6k',6,'6-7k',7,'7-8k',8,'8-9k', 9,'9-10k','> 10K') "size",
count(*),ksmchcls Status, sum(ksmchsiz) Bytes
from x$ksmsp
where KSMCHCOM = 'free memory'
group by ksmchidx, ksmchcls,
'sga heap('||KSMCHIDX||',0)',ksmchcom, ksmchcls,decode(round(ksmchsiz/1000),0,'0-1K',
1,'1-2K', 2,'2-3K', 3,'3-4K',4,'4-5K',5,'5-6k',6,'6-7k',7,'7-8k',8,'8-9k', 9,'9-10k','> 10K');
来源:oschina
链接:https://my.oschina.net/u/3967174/blog/2245075