一、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自身信息的表或者視圖java
二、硬解析、軟解析
硬解析步驟:語法,對象是否存在,用戶是否有權限操做對象,生成執行計劃,挑選最終執行計劃(消耗大量資源佔解析的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消耗,總解析,硬解析,解析失敗linux
三、SQL共享,sql徹底相同,(每個字母必須相同)
綁定變量
SQL語句組成,動態部分、靜態部分
cursor_sharing: [FORCE | SIMILAR | EXACT]
FORCE 字面值強制綁定,不管是否最佳
SIMILAR 字面值強制綁定,同時選用最佳效率
EXACT 字面值嚴格徹底相同判斷
show parameter cursor;
alter system set cursor_sharing = exact scope = both; sql
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 '';數據庫
四、找出沒有共享的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;windows
五、解析命中率,軟解析成功的次數>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;緩存
六、解決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時發生,緣由是共享池空間不足和碎片過多
一、alter system flush shared_pool; --清理碎片,碎片程度查看方法
二、共享SQL
alter system set cursor_sharing ='force';
三、強制緩存技術,手動緩存較大的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
四、保留區,達到保留區對象大小時自動緩存,專門緩存大對象
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
五、增長shared pool空間
alter system set shared_pool_size=150M scope=both;
六、按期清理鏈接與實例重啓
select COMPONENT,CURRENT_SIZE from V$SGA_DYNAMIC_COMPONENTS; #當前值
show parameter sga_target:動態參數,統一分配
show parameter sga_max_size:靜態參數,防止動態修改的sga_target設置過大,先修改sga_max_size,重啓session
七、查看執行計劃
select SQL_ID,sql_text,EXECUTIONS from v$sql where SQL_TEXT;
select * from table(dbms_xplan.display_cursor('bwhzpth8a3zgv'));--經過sqlid查看執行計劃併發
八、在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;
查詢該設置大小oracle
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);
九、補充內容
查詢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 解析外的時間即執行查詢時間,若是很低說明解析次數多oop
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');