一
.
简介
:
数据库调整中最为重要的一部分是重写运行效率差的
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
模式中是相等,可使用缓存的已分析代码
.