一
.
簡介
:
數據庫調整中最爲重要的一部分是重寫運行效率差的
SQL
代碼
,
重寫以後的
SQL
代碼在運行效率方面可能會與以前的產生極大的差異!
可是當遇到重寫以後性能仍是未能突破瓶頸或者你是用戶
(
沒法訪問
SQL
代碼
)
的時候
,
能夠經過調整
ORACLE
的共享內存結構
SGA(System Global Area),
最大限度地提升性能!
SGA
中比較重要的組件就是
Shared Pool(
共享池
),
它的做用就是高速緩存
SQL
語句
!
共享池由一個最近最少使用
(LRU,Least Recently Used)
算法來管理
!
共享池的好處
:
1.select cust_id,cust_name from col_cust
2.
上列語句的算法被轉換成
ASCII
碼
,
而後經過一個散列算法產生一個單獨的散列值
~~
接着
Process
會查看該散列值在
Shared Pool
中是否存在
,
若是存在
,
就執行高速緩存中語句
3.
若是不存在
,
就必須對該語句進行語法分析
,
這些分析步驟會產生額外的系統開銷
,
該操做是高代價的
!
4.
查找到匹配的
SQL
叫作一次高速緩衝區命中
(Cache Hit)
5.
反之叫作高速緩衝區脫靶
(Cache Miss)
6.
注意是區分大小寫的
SELECT CUST_ID,CUST_NAME FROM COL_CUST
二
.
共享池有三個組件組成
,Library Cache(
庫高速緩存區
),Data Dictionary Cache(
數據目錄高速緩存區
),User Global Area(
用戶全局區
)
1.Library Cache(
庫高速緩存區
)
是用來緩存
SQL
語句的場所
.
能夠經過下面這句話對動態視圖進行查詢
,
檢查
Library Cache
的內容
select p.username,l.sql_text,
lpad(' ' ,4*(LEVEL-2)) || operation || ' ' || options || ' ' || object_name as "Execution Plan"
from (
select s.username,p.address,p.hash_value,p.operation,p.options,p.object_name,p.id,p.parent_id
from v$sql_plan p,v$session s
where (p.address=s.sql_address and p.hash_value=s.sql_hash_value) and s.username='citictest'
) p,v$sql l
where(l.address=p.address and l.hash_value=p.hash_value)
start with id=0
connect by prior id = parent_id
2.Data Dictionary Cache(
數據目錄高速緩存區
):
數據目錄是用來檢查
SQL
語句所引用的那些表是否已經存在
,
列名和數據類型是否也正確
! Library Cache
和
Data Dictionary Cache
使用互相獨立的
LRU
機制
,
好處是後續用戶發佈的語句與先前用戶所發佈的語句相似但不一致
,
雖然在
Library Cache
中沒法找到匹配的
,
可是在數據目錄中會存在
,
也會有性能上的提升。
三
.(1)
測量
Library Cache(
庫高速緩存區
)
的性能
select namespace,gethitratio,pinhitratio,reloads,invalidations
from v$librarycache
where namespace in ('SQL_AREA','TABLE/PROCEDURE','BODY','TRIGGER');
主要看
gethitratio,pinhitratio>90%
說明調整充分
select sum(reloads)/sum(pins) "RELOAD
RATIO"
from v$librarycache
當
<1%
意味着不是常常從新語法分析之前被裝載到
Library Cache
的語句
(2)
測量
Data Dictionary Cache(
數據目錄高速緩存區
)
的性能
select 1 - (sum(getmisses)/sum(gets)) "DATA DICTIONARY HIT RATIO"
from v$rowcache;
當
>85%
時說明調整充分
四
.
經過改進
Library Cache
和
Data Dictionary Cache
來提升
shared pool
性能
(1).
獲得當前
shared pool
的大小
select pool,sum(bytes) "SIZE" from v$sgastat where pool='shared pool' group by pool;
(2).
獲得推薦的
shared pool
大小
set echo off
set feedback off
set serveroutput on
declare
v_total_plsql_mem number := 0;
v_total_sql_mem number := 0;
v_total_sharable_mem number := 0;
begin
select sum(sharable_mem) into v_total_plsql_mem from v$db_object_cache;
select sum(sharable_mem) into v_total_sql_mem from v$sqlarea where executions > 10;
v_total_sharable_mem := v_total_plsql_mem + v_total_sql_mem;
Dbms_Output.put_line('Estimated required shared pool size is:' || to_char(v_total_sharable_mem,'fm9,999,999,999,999') || ' bytes');
end;
/
(3).
動態加大
shared pool
大小
alert system set shared_pool_size = 200M;
*
大小不能超過
SGA_MAX_SIZE
的值
(4).
初始
SGA
大小的計算
(TSGA)SGA
總的大小
=
服務器物理內存
*0.55 (1G
以上物理內存的話能夠相應
60%-75%)
(TSGAI)
每一個實例的總
SGA
大小
=TSGA/oracle
上實例的個數
shared pool
的總內存
=TSGAI*0.45
(5).
上述四點是其實完成的是同一個作法,就是使
Shared Pool
更大
(6).
能夠將
PL/SQL
程序包裝入
Shared Pool Reserved Area(
共享池保留區
)
Shared_Pool_Reserved_Size
用來設置這一區域的大小,默認是
5%
,這是不夠的
select owner,name,sharable_mem from v$db_object_cache
where type in('PACKAGE','PACKAGE BODY') order by sharable_mem desc;
上述這句語句能夠查看當前緩存區中的
PL/SQL
程序包的名稱和大小,當發現大小
> Shared_Pool_Reserved_Size
時說明保留區的大小不夠,你須要增長
Shared_Pool_Reserved_Size
的值
(7).
把重要的
PL/SQL
代碼保持在內存中
你能夠把經常使用的
PROCEDURE
銷定
(Pinning)
在
Shared_Pool_Reserved_Size
中
作法以下
:
a)sys
用戶登陸
b)
運行
@%ORACLE_HOME%/rdbms\admin\dbmspool.sql
c)SQL>execute DBMS_SHARED_POOL.KEEP('PROCEDURENAME') (
銷定
,
必須用
sys
完成
)
d)
找到銷定的對象
select owner,name,type from v$db_object_cache where kept='YES';
e)
銷定對單獨的
SQL
語句沒法操做
,
儘量的把大語句作成
PROCEDURE
,能夠用一下語句尋找出比較大的語句
select substr(sql_text,1,45),length(sql_text) "STMT_SIZE" from v$sqlarea where command_type=47 order by length(sql_text) desc;
f)
能夠編寫一個腳本,當實例啓動以後運行,把全部須要銷定的語句執行一下
h)
只有使用
UNKEEP
或者實例關閉時纔會取消銷定
(8).
其餘的一些調整
Library Cache
參數
a)open_cursors :
默認
50
b)cursor_space_for_time
默認
false
c)session_cached_cursors
默認
0(
無遊標高速緩存
)
d)cursor_sharing
默認
EXACT --2
條
SQL
語句必須徹底匹配才能共享
shared pool
中所緩存的已分析代碼
.
SIMILAR --
容許
2
條僅在字面上不一樣的
SQL
語句共享
shared pool
中所緩存的已分析代碼
.
例如
:select cust_id from col_cust where cust_name = 'wang'
select cust_id from col_cust where cust_name = 'huang'
上述兩句在
SIMILAR
模式中是相等,可使用緩存的已分析代碼
.