statspack 部署
statpack 是两个高峰期快照的对比
设置参数 timed_statistics =TRUE
select name from v$datafile;
1、create tablespace perf_tbs datefile '/u01/oracle/oradata/prod/perf_tbs01.dbf' size 200m;
2、@?/rdbms/admin/spcreate 输入密码和默认的表空间和临时的表空间
3、execute statspack.snap (快照的级别越高统计的信息越多 默认的是5级 已经够了 可以修改他的默认级别 或者是做快照的时候指定级别 desc statspack
指定快照级别为7 execute statspack.snap(I_SNAP_LEVEL=>7);
修改他默认级别 execute statspack.modify_statspack_parameter(I_SNAP_LEVEL=>7) )
怎样产生报告:@$ORACLE_HOME/rdbms/admin/spreport 输入开始快照和结束快照 产生的名字
单独的用analyze 整个的用DBMS_STATS
V$打头的是视图 X$打头的是基表 基表跟视图一样 只不过是基表里一些名字都是缩写看不懂 额视图更直观
数据库中有可能发生等待事件的名字 放在 V$event_name
V$SYSTEM_EVENT 数据库开启以后 已经发生的等待事件
V$SESSION 获得当前登录用户的信息
V$SESSTAT 所有会话的统计
V$SESSION_EVENT 所有会话等待信息
V$SESSION_WAIT 当前会话正在等待的会话信息
列出当前会话的统计信息
select se.sid,se.serial#,se.username,st.class,st.name,ses.value
from v$session se,v$statname st,v$sesstat ses
where se.sid=ses.sid
and ses.statistic#=st.statistic#
and se.username is not null
and se.username <> 'sys'
and ses.value <> 0;
列出PGA消耗超过300K的统计信息
select username,name,value
from v$statname n,v$session s,v$sesstat t
where s.sid=t.sid
and n.statistic#=t.statistic#
and s.type='user'
and s.username is not null
and n.name='session pga memory'
and t.value > 30000;
oracle调优步骤
1、制定一个调优的范围 例如:通过STATSpack 信息 查找tablespace IO stats 这个表一天 读数 据块的 总量 57178198*1.1*8/1024+写数据块的总量350447*4*8/1024
2、收集数据
3、查看,编辑数据和规则
4、分析数据
5、回顾一下这个建议
调整共享池
一个SQL语句在执行过程中有4个流程
1、parse 解析:a.搜索共享池的库缓冲区,查看该语句是否曾经执行过,如果是第一次执行则进入下一步b.检查语法,对象,权限,这些信息包含在system表空间中,访问过的数据字典存放在共享池的数据字典缓冲区 c.分析过程中锁表 d.oracle优化器根据表的存储结构(表的存储类型,索引,物化视图等等)根据CBO(CBO是什么)的规则 选择最佳路径 产生执行计划,编译并存储到共享池的库缓冲区,以便共享。 这一过程叫做硬解析
2、bind
绑定变量
例如:
select * from emp where empno=7369
select * from emp where empno=7788
select * from emp where empno=7654
desc v$sqlarea
select SQL_TEXT,SHARABLE_MEM,EXECUTIONS from v$sqlarea where sql_test like 'select * from emp%';
如果使用绑定变量
variable v_empno number;
exec :v_empno :=7788
select * from emp where empno=:v_empno;
exec :v_empno :=7654
select * from emp where empno=:v_empno;
select SQL_TEXT,SHARABLE_MEM,EXECUTIONS from v$sqlarea where sql_test like 'select * from emp%';
3、execte
先从数据缓冲区搜索数据块,如果不存在,则从数据文件中读取,存放在数据缓冲区中,以便共享
4、fetch
把结果返回给用户
共享池的大小由shared_pool_size
设置库缓冲区是为了减少硬解析
怎样判断共享池大小多少合适
Executes PROC1 --> 1st pin, 1 load
Executes PROC1 --> 2nd pin, no reload
Executes PROC1 --> 3rd pin, no reload
Executes PROC1 --> 4th pin, no reload
执行了4次没有发生reload
reload 超过1% 就要增加共享池大小
我们可以通过查询来确认
select sum(pins)"Executions",sum(reloads)"Cache Misses",sum(reloads)/sum(pins) from v$librarycache
看statpack报告 查找Advisory shared pool
Shared Pool Advisory for DB: EDMINC01 Instance: EDMINC01 End Snap: 23
-> Note there is often a 1:Many correlation between a single logical object
in the Library Cache, and the physical number of memory objects associated
with it. Therefore comparing the number of Lib Cache objects (e.g. in
v$librarycache), with the number of Lib Cache Memory Objects is invalid
Estd
Shared Pool SP Estd Estd Estd Lib LC Time
Size for Size Lib Cache Lib Cache Cache Time Saved Estd Lib Cache
Estim (M) Factr Size (M) Mem Obj Saved (s) Factr Mem Obj Hits
----------- ----- ---------- ------------ ------------ ------- ---------------
224 .5 196 13,414 3,312,181 1.0 502,602,217
272 .7 243 15,332 3,312,790 1.0 502,671,119
320 .8 290 16,265 3,313,270 1.0 502,722,414
368 .9 338 17,140 3,313,567 1.0 502,772,748
416 1.0 385 17,975 3,313,807 1.0 502,866,630
464 1.1 431 18,461 3,313,976 1.0 502,929,749
512 1.2 478 18,973 3,314,178 1.0 503,014,635
560 1.3 525 20,406 3,314,353 1.0 503,069,431
608 1.5 572 22,539 3,314,446 1.0 503,098,080
656 1.6 619 27,732 3,314,504 1.0 503,128,303
704 1.7 665 29,823 3,314,583 1.0 503,167,429
752 1.8 712 33,914 3,314,652 1.0 503,203,735
800 1.9 759 36,003 3,314,747 1.0 503,251,023
848 2.0 808 41,502 3,314,895 1.0 503,285,919
-------------------------------------------------------------
1.0 是当前shared pool 的尺寸 416M 假如我把共享池变为2倍 848 则 被保留的可能性 还是1 如果变为二分之一 224M 则保留还是1 所以 没什么区别 所以可以把共享池调整为224M
对表进行分析有好处 让ORACLE及时对表有个了解 选择最佳的CBO 如果
库缓冲区调优 :通过下面方法避免碎片:
1、为大内存分配需求保留空间,为大的对象来分配出一个保留的空间 shared_pool_reserved_size 这个值
2、将经常调用的大对象保留在共享池中
查在共享池当中你的代码占得空间超过100K的:
select * from v$db_object_cache
where sharable_mem >100000
and (type='PACKAGE' or type='PACKAGE BODY' or type='FUNCTION' or type='PROCEDURE)
and KEPT='NO';
为了避免把经常用的语句AGE OUT出去 我们可以 用
execute dbms_shared_pool.keep('SYS.STANDARD');
3、为oracle共享服务器
分为专用连接:一个user进程 一个server进程 一个PGA 这个server进程和PGA只为user服务
共享连接: 一个user进程 dispatcher(分发器)进程 这个用户进程是跟分发器对应的
本地连接都是专用连接 连接之前声明oracle_sid
远程连接都是共享连接
共享连接 你应该在你的服务器上配置一个dispatcher进程 一个shared server 进程
alter system set DISPATCHERS = '(PROTOCOL=TCP)(DISPATCHERS=3)';
ps -ef |grep ora_
alter system set SHARED_SERVERS = 5;
ps -ef |grep ora_
cd /u01/app/oracle/product/10.2.0/db_1/network/admin
ls
vi tnsnames.ora
在第三组上 添加一个
(server = DEDICATED)
在最后添加
CUUG95_sh=
(DESCRIPITION =
(ADDRESS=(PROTOCTL = tcp)(HOST = cuug95)(PORT = 1521))
(CONNECT_DATA =
(server = shared)
(SERVICE_NAME = prod)
)
)
sqlplus scott/tiger@CUUG95_sh
UGA:
如果是专用连接 UGA 放在PGA中
如果是共享连接 UGA放在share pool中 如果做共享连接 就分配一个large pool
共享池保留区域是否合适
select FREE_SPACE,REQUEST_MISSES,ABORTED_REQUEST_THRESHOLD from v$shared_pool_reserved
如果REQUEST_MISSES为0 或者接近0 那么说明 我们保留区域设置的是合适的 如果FREE_SPACE>保留区域的50%
shared_pool_reserved_size这个参数是改尺寸的
其它影响库缓冲区的参数
OPEN_CURSORS 一个会话打开多少游标
SESSION_CACHED_CURSORS 如果这个会话执行相同的SQL语句 会保留多少 这样在执行的时候就不需要软解析了 在STATSPACK中Instance Efficiency Percentages
如果软解析soft parse的百分比很高 跳过解析execute to parse的百分比很低 那就说明你的软解析很高 这个就可以设置 SESSION_CACHED_CURSORS这个参数
数据字典缓冲区 衡量的标准是命中率
在STATSPACK描述数据字典缓冲区章节
经常使用的数据字典对象的miss率应该小于2%
整个数据字典缓冲区miss率小于15%
大池:
1,备份恢复 如果没有分配大池 RMAN就会用共享池的空间
2,共享服务器的连接
3,并行
同步IO 一个进程读完第一个块 就写一个块
异步IO 多个进程 第一个进程读第一个块 第二个进程写第一个块 同时 第一个进程在读第二个块
数据缓存区管理
对象在数据缓存区保留的时间越长 那么数据缓存区的命中率越高
数据缓存区调优顾问能预测其在不同大小的数据库性能 通过设置DB_CACHE_ADVICE参值来开启数据缓冲区 3个参数 如果实例起来 你的参数是OFF 不能直接变为on 需要重启实例 如果参数是ready 可以变为on
数据缓存区调优方向和技巧
尽量从内存中查询数据
在OLTP环境中 数据逻辑读的命中率应该是90%以上
出现以下情况要增加数据缓存区大小:
数据逻辑读的命中率小于90%
测量缓冲区的命中率
select 1-(phy.value - lob.value - dir.value) / ses.value "CACHE HIT RATIO" from v$sysstat ses, v$sysstat lob, v$sysstat dir,v$sysstat phy where ses.name = 'session logical reads' AND dir.name = 'physical reads direct' AND lob.name ='physical reads direct(lob)' AND phy.name = 'physical reads';
物理直接读的意思是 直接从磁盘中读 磁盘-操作系统缓存区-sga缓存区 如果SGA缓存区中没有找到 在操作系统缓存区找到 就不叫物理直接读
使用多个数据缓冲区
KEEP pool 有数据块放在keep pool中 不会被AGE OUT 缓存的数据块能被重复访问的和表的大小是default pool的10%
recycle pool 不会被保留 访问一次的表不在访问的和表的大小至少是默认池的2倍
alter table emp storage (buffer_pool keep)
alter table emp storage (buffer_pool recycle)
查看表被放在了哪个池中
desc user_tables
select table_name,buffer_pool from user_tables;
analyze table emp estimate statistics;
select ,blocks
其他关于数据缓冲区视图
select name ,value from v$sysstat
where name='free buffer inspected'; 如果这个直在不断的增加 就说明oracle释放缓存区空间困难 我们就要增加数据缓存区空间
热块:如果热块是属于断头的块 是因为由于并发insert操作引起的 解决办法:分配多个freelist列表 健表时候指定freelist数量 2,把表存放在段空间自动管理的表空间 段空间自动管理跟手动管理的区别 如果是自动管理的话 oracle 一般会拿3个块来记录freelist 手动的话 一般是一个
如果这个热块属于回滚段头的块:多个事务使用同一个回滚段造成。。
解决办法:尽量少的事务同时使用一个回滚段
如果这个热块属于普通的数据块(存放行数据):由于多个事务访问同一块当中相同或者不同的行
解决办法:用尺寸小的数据块 pctfree设置的更大
log_buffer调整的目标
1,保证log_buffer始终都有可用的空间(1,分配合适的log_buffer尺寸 默认值是500K左右 一般大于1m的log_buffer对于性能方面没有多大的帮助 2,尽可能的让lgwr写的快 a,怎样让lgwr写的快 把redolog文件存放在磁盘i/o最强的磁盘上 b,保证lgwr始终都有可用的日志组可写
日志组有4种状态:
current 当前日志组
active 表示记录在给日志组中的事务所造成的数据块的改变,没有完全从数据缓冲区写入数据文件,处于该状态的日志组不允许被覆盖
inactive 表示记录在给日志组中的事务所造成的数据块的改变,完全从数据缓冲区写入数据文件,处于该状态的日志组不允许被覆盖
unused 未使用的
select sid,event,seconds_in_wait, state from v$session_wait where event ='log buffer space';
2,减少redo日志 在导入数据的时候如果是非归档,可以不产生redo日志,提高导入速度 如果是归档的 可以使用nologging 一些sql语句也可以跟nologging 因为是不产生日志所以导入数据完成以后要做备份
其他的缓冲区
java池 的大小由java_pool_size这个参数 10g 一般默认50m
select * from v$sgastat where pool ='java pool'; 空闲空间小于java池的二分之一 分配的太少
I/O 性能调整指导方针
性能调整的基本规则:
1、从不同的磁盘和控制器中读取数据 这样做的好处是:可以增加我们的I/O吞吐量
2、尽可能使用表空间本地化管理 这样做的好处是:减少数据字典的压力,当空间分配和回收的时候 不会产生UNDO数据
通过设备分布文件:
1、将数据文件和redo日志文件分别存放在不同的存储介质中 减少两者的IO争用
2、表数据条带 数据的多样性
3、把数据文件存放在裸设备上提高性能百分比 提高将近20%的性能 因为:避开了文件系统这一层
对IO进行诊断的工具
通过视图
IO统计信息
select d.tablespace_name TABLESPACE, d.file_name, f.phyrds,f.phyblkrd,f.readtim, f.phywrts, f.phyblkwrt,f.writetim
from v$filestat f,dba_data
文件条带:
操作系统条带:使用条带软件 或者是阵列 raid 技术条带
人工条带: 一个EMP表 放在USER表空间上 这USER表空间有3个数据文件 EMP表会随机放在一个数据文件上 并不是放在3个数据文件上 这样就没有达到条带的效果 所以我们要人工条带
查看表存放在哪个表空间
desc dba_extents
select file_id,block_id blocks from dba_extents where owner='SCOTT'
alter table test3 allocate extent(size 1m datafile'.........')
调整全表扫描操作
如果你这个应用是 必须要全表扫描 就没法建索引
指定db_file_multiblock_read_count
检查点:是用来确认从什么位置开始做recovery
频繁产生检查点: 减少实例
通过调整以下参数:
db_block_max_dirty_target
mttr
排序区的调整
排序区 是放在UGA中
如果是专用服务连接 UGA在PGA中
如果是共享服务连接 放在共享池 如果排序比较频繁 不宜用共享服务连接
排序区 参数(只支持字节) 这两个参数值一样的 sort_area_size 和sort_area_retained_size 这个参数的用途是 当你排序完成以后 oracle会把排序区缩小到多少 这样的好处是提高内存的使用率 一般情况下我们不这么做 这样做会导致再次发生排序 除非内存比较频繁
自动管理排序区域参数:pga_aggregate_target (范围10M-4T) 这个值:一般系统的内存-sga分配的内存-系统的其他应用程序
workarea_size_policy 是否自动分配 AUTO|MANUAL
为了提高建大量索引的速度 我们可以再建索引之前 给他分配一个较大的 sort_area_size alter session set sort_area_size=
排序调优
1、尽可能避免排序操作
2、尽可能将所有排序操作在内存完成
3、给临时表空间分配足够的空间,减少以后空间分配的调用
例子:
desc v$tempfile
select name fron v$tempfile;
删除所有临时表的数据文件 删除以后 10g还会自己创建 我们可以这样做:
然后 我们让oracle做一个比较大的排序操作
insert into test3 as select * from test3
重复执行上条语句 多插入一些
create index test3_empno on test3(empno);
会报错 ora-00600错误 internal error code,arguments:
哪些操作需要排序:
1、创建索引
2、并行插入数据
3、使用distinct union intersect minus order by group by
4、analyze
避免排序:
1、我们可以创建索引的时候 使用nosort 针对的是 在做SQL LOADER
2、尽量使用union all 替换union union必须结构一样
select * from test2
union
select * from emp
这样查出来的是 两张表合并 然后去掉重复的
如果使用union all 不去掉重复的
3、做表连接时使用索引访问
set autotrace traceonly
create table dept2 as select * from dept;
select d.dname,e.ename,e.sal
from dept2 d,test3 e
where d.deptno=e.deptno
调整回滚段
回滚段的扩展 例如 回滚段有4个区 依次写入 如果写到4 该写1的时候 1还处于active状态 这样 oracle回增加一个回滚段5 这就叫做 回滚段的扩展
回滚段的调优目标
1、事务访问会滚段时不应该有等待事件 会滚段头部的冲突诊断 select sum(waits)*100 / sum(gets) "Ratio",sum(waits) "Waits" sum )
2、在正常运行时不应该扩展回滚段 每个回滚段有合适尺寸的区 一个回滚段 初始化区和下一个区都分配20个 回滚段发生扩展的几率大大的减少
如果删除事务 (删除的事务放在回滚段)的大小 超过UNDO表空间的大小
select name from v$datafile
show parameters undo
create undo tablespace undotbs2 datafile'.........'size 3m;
alter system set undo_tablespace=undotbs2
我们删除一个大表
delete test3
会报错 ora-30036 错误 操作失败 回滚段的表空间不够大
查看一下回滚段 select segment_name,tablespace_name,status from dba_rollback_segs;
查看表空间有多少可用空间
select tablespace_name,sum(bytes)/1024/1024 mb from dba_free_space group by 1;这个查询语句不适合undo表空间
3、用户和应用程序应该尽量使用少的回滚段 用户应该尽量commit
4、不能存在耗尽回滚段空间的事务
5、查询请求总是能够获取读一致性的镜像
回滚段过小产生的问题:
会产生快照太老 报错 ora-01555
什么叫快照太老? 例如现在有一个很大的表 有10000个数据块 9点钟 第一个事务T1 做了一个update操作 这个操作改变了 9000位置的一个块 oracle会把这个改变放在undo段 9点10分钟 T2事务做了一个全表扫描 9点20 T1 commit 9点30 T3事务 做了delete 放在了刚才放T1事务产生的回滚段的位置(undo段太小才会放在T1位置上) 当T2事务全表扫描到9000块的时候 会去UNDO段找 会产生一个错误 快照太老
参数:undo_retention 已提交的事务保留在undo段多长时间
undo_management=auto manual 设定UNDO表空间自动管理
undo表空间手动管理;
select* from v$rollname; 当前online的undo表空间
自动表空间管理 是oracle给你分配几个undo段
手动就不给你分配 没有分配undo段 就做不了 dml 操作
自己创建undo段create tablespace rbs datafile'.....'size 20m segment space management manual
select
create rollback segment temp tablespace system;
alter rollback segment temp online;
create rollback segment r01 tablespace rbs
storage(initial 1280k next 1280k) 1280K 是64K 乘以20个
alter rollback segment r01 online;
下次重启实例的时候 还要online
这时候我们要加参数
show parameter roll
alter system set rollback_segment =r01,r02....
如果是自动管理undo段 oracle会把每个事物分配到一个undo段 等到分配到30个的时候 oralce不会在扩展 会2个事务使用一个
看statspack 查看一下 rollback segment stats for db
手动管理的好处
让事务使用哪个回滚段
set transaction use rollback segment r01
当前事务用的是哪个回滚段
select s.username ,t.xidusn,t.used_ublk from v$session s ,v$transaction t where s.saddr=t.ses_addr:
应用的调整(重要)
一、数据的访问方式
1、cluster表 把两张表的数据放在一起 经常从两个表中获取数据 如果不建立cluster会增加IO
create cluster emp_dept (deptno NUMBER(2)) TABLESPACE users 建立cluster表的时候 应该通过一个在两个表中相关联的列 叫做簇键
create table dept_clu
(deptno number(2)
dname varchar(2)
loc varchar(13)
)
cluster emp_dept(deptno);
建表的时候 指定一下cluster emp_dept(deptno) 把这个表放在簇段中
往表中插入数据的时候 我们要建立一个簇索引
create index emp
清空buffer alter system flush buffer_cache;
2、索引 btree
根块里面存放的是 指向枝块的指针
枝块里面存放的是 指向叶块的指针
叶块里面存放的是 索引列的值和rowid
会对索引进行一个排序
位图索引的好处 减少存储的空间
位图索引 适合
在一个表中重复值很多
使用最少的存储空间
适合大表
3、IOT 索引组织表 把基表的数据放在索引块
表中一定要有一个组建和以后经常会通过主键来访问这个表 那么就适合IOT
本文出自 “柒色斑斓” 博客,谢绝转载!