下面是小编为大家收集的如何让Oracle数据库始终保持优良性能,本文共8篇,仅供参考,欢迎大家阅读,希望可以帮助到有需要的朋友。

篇1:如何让Oracle数据库始终保持优良性能
如何让Oracle数据库始终保持其优良的性能,这是许多DBA特别关心的问题,本文将着重对以下几个方面进行详细的介绍,
如何让Oracle数据库始终保持优良性能
,
篇2:如何保持Oracle数据库的优良性能
最近更 新
优化Oracle停机时间及数据库恢复
Oracle Report中加入下载超链接操作方法
Orace查询数据出现乱码的问题解决思路
Oracle PL/SQL入门案例实践
[Oracle] Data Guard 之 浅析Switchover与
Linux系统下导出ORACLE数据库出现Exporti
Oracle时间日期操作方法小结
Oracle捕获问题SQL解决CPU过渡消耗
delete archivelog all无法清除归档日志解
自动备份Oracle数据库
热 点 排 行
ORACLE 10g 安装教程[图文]
oracle常用sql语句
oracle sqlplus 常用命令大全
oracle 触发器 学习笔记
ORACLE常用数值函数、转换函数、
Oracle数据库下载及安装图文操作
oracle中的视图详解
oracle 查询表名以及表的列名
ORACLE数据库查看执行计划的方法
oracle 存储过程和函数例子
篇3:保持Oracle数据库的优良性能数据库
Oracle 数据库 以其高 可靠性 、 安全 性、可 兼容性 ,得到越来越多的企业的青睐,如何使Oracle数据库保持优良 性能 ,这是许多数据库管理员关心的问题,根据笔者经验建议不妨针对以下几个方面加以考虑。 一、分区 根据实际经验,在一个大数据库中,数据空
Oracle数据库以其高可靠性、安全性、可兼容性,得到越来越多的企业的青睐。如何使Oracle数据库保持优良性能,这是许多数据库管理员关心的问题,根据笔者经验建议不妨针对以下几个方面加以考虑。
一、分区
根据实际经验,在一个大数据库中,数据空间的绝大多数是被少量的表所占有。为了简化大型数据库的管理,改善应用的查询性能,一般可以使用分区这种手段。所谓分区就是动态表中的记录分离到若干不同的表空间上,使数据在物理上被分割开来,便于维护、备份、恢复、事务及查询性能。当使用的时候可建立一个连接所有分区的视图,使其在逻辑上仍以一个整体出现。
1.建立分区表
Create table Employee(
EmpNo varchar2(10) primary key,
Name varchar2(30),
DeptNo Number(2)
)
Partition by range(DeptNo)
(partition PART1 values less than (11)
tablespace PART1_TS,
partition PART2 values less than(21)
tablespace PART2_TS,
partition PART3 valuse less than(31)
tablespace PART3_TS
partition PART4 values less than(MAXVALUE)
tablespace PART4_TS
);
表Employee依据DeptNo列进行分区。
2.分区索引
Create index Employee_DeptNo on Employee (DeptNo)local(
partition PART1 tablespace PART1_NDX_TS,
partition PART2 tablespace PART2_NDX_TS,
partition PART3 tablespace PART3_NDX_TS,
partition PART4 tablespace PART4_NDX_TS,
);
当分区中出现许多事务并且要保证所有分区中的数据记录的惟一性时采用全局索引,在建立全局索引时,Global子句允许指定索引的范围值,这个范围值可以不同于表分区的范围值。只有建立局部索引才会使索引分区与表分区间建立起一一对应关系。因此,在大多数情况下,应该使用局部索引分区。若使用了此索引,分区就能够很容易地将索引分区与表分区建立关联,局部索引比全局索引更易于管理。
3.分区管理
根据实际需要,还可以使用Alter table命令来增加、删除、交换、移动、修改、重命名、划分、截短一个已存在分区的结构,
二、重建索引
如果表中记录频繁地被删除或插入,尽管表中的记录总量保持不变,索引空间的使用量会不断增加。虽然记录从索引中被删除,但是该记录索引项的使用空间不能被重新使用。因此,如果表变化不定,索引空间量会不断增加,不论表中记录数量是否增加,只是因为索引中无效空间会增加。
要回收那些曾被删除记录使用的空间,需要使用Alter index rebuild命令。可以做一个定期运行的批处理程序,来重建最活动表的索引。这个批处理程序可以在空闲时运行,以避免该程序与其他应用程序冲突。若能坚持索引的这一程序规划,便可以及时回收那些未使用空间,提高空间利用率。
三、段的碎片整理
当生成一个数据库对象时(一个表或一个索引),通过用户缺省值或指定值来为它指定表空间。一个在表空间中生成的段,用于存储对象的相关数据。在段被关闭、收缩、截断之前,段所分配的空间将不被释放。
一个段是由范围组成,而范围是由相邻的Oracle块组成。一旦存在的范围不能再存储新的数据,这个段就会去获得新的范围,但并不要求这些范围是彼此相邻的。这样的扩展会一直继续下去,直到表空间中的数据文件不能提供更多的自由空间,或者范围数量已达到极限。
因此,一个碎片太多的数据段,不仅会影响运行,也会引发表空间中的空间管理问题。所以,每个数据段只含有一个范围是十分有益的。借助监控系统,可以通过检查DBA_SEGMENTS数据字典视图来了解哪些数据库对象含有10个或更多范围的段,确定其数据段碎片。
若一个段的碎片过多,可用两种方法解决:
1. 用正确的存储参数建立一个新表,将旧表的数据插入到新表中,在删除旧表;
2. 利用Export/Import工具。
如:exp system/manager file=exp.dmpcompress=Y grants=Y indexes=Y
tables=(T1,T2)
若输出成功,进入Oracle,删除上述表。
注:compress=Y表示将在输出过程中修改它们的存储参数。
imp system/manager file=exp.dmp commit=Y buffer=64000 full=Y
四、自由范围的碎片整理
表空间中的一个自由范围是表空间中相连的自由(空间)块的集合。当一个段关闭时,它的范围将被释放,并被标记为自由范围。然而,这些自由范围再也不能与相邻的自由范围合并,它们之间的界线始终存在。但是当表空间的缺省值pctincrease设置不是0时,SMON后台进程会定期将这些相邻的自由范围合作。若pctincrease设置为0,那么相邻自由范围不会被数据库自动合并。但可以使用Alter table命令“coalesce”选项,来强迫进行相邻自由范围的合并。
不进行自由范围合并,在日后的空间请求中,会影响到表空间中的空间分配。当需要一个足够大的范围时,数据库并不会合并相邻的自由范围,除非没有其他选择。这样,当表空间中前面较小的自由范围已被使用时,将使用表空间中后面部分最大的一个自由范围。结果,会因为没有足够多的使用空间,从而导致表空间需求的矛盾。由于这样的情况出现,使数据库的空间分配距理想越来越远。自由空间碎片常会出现在那些经常关闭又重新生成的数据库表和索引中。
在理想的Oracle表空间中,每一个数据库对象存储在一个单独的范围中,并且所有有效自由空间集中在一个巨大而连续的范围中。这样,在一个对象需要附加存储空间时,可以在增加获取足够大自由空间的可能性的同时,最小化空间中的循环调用,提高自由空间使用率。
原文转自:www.ltesting.net
篇4:保持Oracle数据优良性能的若干诀窍
如今,Oracle数据库以其高可靠性、安全性、可兼容性,得到越来越多的企业的青睐,如何使Oracle数据库保持优良性能,这是许多数据库管理员关心的问题,笔者建议不妨针对以下几个方面加以考虑。
分区
1. 建立分区表
Create table Employee ( EmpNo varchar2(10) primary key, Name varchar2(30), DeptNo Number(2) ) Partition by range(DeptNo) ( partition PART1 values less than (11) tablespace PART1_TS, partition PART2 values less than (21) tablespace PART2_TS, partition PART3 values less than (31) tablespace PART3_TS partition PART4 values less than (MAXvalue) tablespace PART4_TS );
表Employee依据DeptNo列进行分区。
当分区中出现许多事务并且要保证所有分区中的数据记录的惟一性时采用全局索引,在建立全局索引时,Global子句允许指定索引的范围值,这个范围值可以不同于表分区的范围值,
只有建立局部索引才会使索引分区与表分区间建立起一一对应关系。因此,在大多数情况下,应该使用局部索引分区。若使用了此索引,分区就能够很容易地将索引分区与表分区建立关联,局部索引比全局索引更易于管理。
[next]3. 分区管理
重建索引
如果表中记录频繁地被删除或插入,尽管表中的记录总量保持不变,索引空间的使用量会不断增加。虽然记录从索引中被删除,但是该记录索引项的使用空间不能被重新使用。因此,如果表变化不定,索引空间量会不断增加,不论表中记录数量是否增加,只是因为索引中无效空间会增加。
段的碎片整理
一个段是由范围组成,而范围是由相邻的Oracle块组成。一旦存在的范围不能再存储新的数据,这个段就会去获得新的范围,但并不要求这些范围是彼此相邻的。这样的扩展会一直继续下去,直到表空间中的数据文件不能提供更多的自由空间,或者范围数量已达到极限。
若一个段的碎片过多,可用两种方法解决:
1. 用正确的存储参数建立一个新表,将旧表中的数据插入到新表中,再删除旧表;
2. 利用Export/Import工具。
如:
篇5:Oracle Freelist和HWM原理探讨及相关性能优化数据库教程
oracle|性能|优化
Oracle Freelist和HWM原理探讨及相关性能优化
中兴通讯重庆研究所 游波
关键词:Freelist,HWM,存储参数,段,块,dump,优化
文章摘要:
近期来,FreeList的重要作用逐渐为Oracle DBA所认识,网上也出现一些相关的讨论,本文以FreeList为线索对Oracle的存储管理的原理进行较深入的探讨,涉及Oracle段区块管理的原理,FreeList算法等。而与FreeList密切相关的一个重用特性HWM,与sql性能密切相关,本文也作了原理分析介绍。在原理探讨的基础上,介绍了常用的存储参数分析方法,并对所涉及的存储优化、HWM的优化和Freelist竞争优化作了说明。
缩略语:
ASSM:auto segement space management
HWM:high water mark
DBA:data block address
OLTP:online transaction process
OPS:oracle parallel server
1.简介
Oracle的空间管理和存储参数管理是Oracle管理及优化的重要部分。FreeList作为Oracle底层存储参数中的核心参数,其行为方式对Oracle的存储管理及性能优化有重大影响,而现有的Oracle文档对此方面的内容比较缺乏。虽然Oracle 9i已出现了ASSM,但是作为深入调优对FreeList认识仍是必要的。
近期来,FreeList的重要作用逐渐为Oracle DBA所认识,网上也出现一些相关的讨论。本文以FreeList为线索对Oracle的存储管理的原理进行较深入的探讨,涉及Oracle段区块管理的原理,FreeList算法等。而与FreeList密切相关的一个重用特性HWM,与sql性能密切相关,本文也作了原理分析介绍。在原理探讨的基础上,介绍了常用的存储参数分析方法,并对所涉及的存储优化、HWM的优化和Freelist竞争优化作了说明。
这些原理分析和性能优化都建立在探讨的基础上,限于篇幅和本人经验可能存在局限、偏差或谬误。
为了准确文中部分结构和字段的说明直接用英文描述。
限于篇幅本文不对同样很重要的block结构作更深入的讨论,对OPS性能有重要影响的free list group本文也未提及,因此本文在单一free list group下讨论。对于block的深入讨论、free list group的介绍与优化以及PCTUSED和PCTFREE等重要参数的优化请参见参考文献和资料。
2.原理探讨
FreeList作为一个Oracle存储管理的核心参数。其行为方式由Oralce内部控制,我们一般不需要掌握和控制。但是我们可能会遇到这些问题,当插入一条记录,会插入到那个块中?是使用新块,还是插入有数据的老块?段是什么时候扩展的,如何扩展的?表中只有一条记录,但是作一次select时代价却是上千个块,为什么?如果我们从原理上清楚了Oracle的存储管理方式,对相关这些问题的解决及性能优化就清晰自然了。
2.1 Oracle的逻辑储存结构
Oralce的逻辑存储结构按表空间,段,区,块进行管理。块是Oracle用来管理存储空间的最基本单元,Oracle数据库在进行输入输出操作时,都是以块为单位进行逻辑读写操作的。区由一系列连续的块组成,Oralce在进行空间分配、回收和管理时是以区为基本单位的。段由多个区组成,这些区可以是连续的也可以是不连续的,一般情况下一个对象拥有一个段。表空间中容纳段和区。
在生成段的时候,会同时分配初始区(initial extents), 初始区的第一个块就格式化为segment header,并被用来记录free list描述信息、extents信息,HWM信息等。
2.2 free list概念
free list是一种单向链表用于定位可以接收数据的块,在字典管理方式的表空间中,Oracle使用free list来管理未分配的存储块。Oracle记录了有空闲空间的块用于insert或Update。空闲空间来源于两种方式:1.段中所有超过HWM的块,这些块已经分配给段了,但是还未被使用。2.段中所有在HWM下的且链入了free list的块,可以被重用。free list具有下列属性
l flag指示free list 被使用(1)或未使用(0)
l free list 链的首块的地址DBA(data block address)
l free list 链的尾块的地址DBA
free list 的信息通常保留在segment header中,这里给出segment header block dump片段加以说明:
nfl = 3, nfb = 1 typ = 1 nxf = 0
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
SEG LST:: flg: USED lhd: 0x03c00233 ltl: 0x03c00233
SEG LST:: flg: USED lhd: 0x03c00234 ltl: 0x03c00234
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
Segment Header:
==> nfl: number of free lists/block
==> nfb: number of free list blocks + segment header
==> typ: block type
==> nxf: number of transaction free lists
Segment List:
==> flg: flag USED or UNUSED the free list
==> lhd: head of free list
==> ltl: tail of free list
在每一个块中都有一个标记flg用来表明块是否链入了 free list链中。如果这个标志置上,该块中后向指针指向free list链中下一个块的DBA。如果当前块是链的最末尾的块,该后向指针值为0。
这里给出位于free list上的block dump的片段
Block header dump: 0x03c00235
Object id on Block? Y
seg/obj: 0xe2d8 csc: 0x00.6264c61 itc: 1 flg: O typ: 1 - DATA
fsl: 1 fnx: 0x3c00234 ver: 0x01
==> Seg/obj Object ID in dictionary
==> csc SCN of last block cleanout
==> itc Number of ITL slots
==> flg O = On freelist , - = Not on freelist
==> typ 1 = DATA 2 = INDEX
==> fsl ITL TX freelist slot
==> fnx DBA of NEXT block on freelist
举例来说如果有五个块在free list中,分别为A,B,C,D,E
就会形成segment header->A->B->C->D->E--|
同时segment header->E
2.3 free list类别
在段中存在3类free list, 即Master Freelists (MFL), Process Freelists (PrFL), 和 Transaction Freelists.
2.3.1 Master Free List(公用空闲空间池):
每一个段中有一个Master free list,在段创建的时候自动生成。对于每一个段来说都有这样一个空闲空间池,对每个进程都是公用的,空闲空间就是位于master free list 的块上。由于Master free list是公用的,因此当多个进程同时插入行到同一个段上,master free list竞争使用程度就会增加。
2.3.2 Process Free Lists
为了减少Master Free list的竞争问题, 引入了另一种free list叫做Process free lists, 根据sql命令 CREATE/ALTER 中的参数FREELISTS 创建. 这样多个free list 就可以分摊空闲空间的管理,以提高OLTP应用作高度并发插入和更新事务时空间分配管理的性能。通过指定CREATE TABLE / CLUSTER or INDEX的子句STORAGE的参数FREELISTS 来创建,例如: CREATE TABLE flg ( . . . .) . . . STORAGE ( ... FREELISTS 10 ...)。缺省的FREELISTS为1,此时不会创建Process free lists。当FREELISTS>=2时,创建Process free lists。
进程在使用process free list是根据进程的Oracle PID (Process ID)来选择的,公式如下:
select list entry = (PID % NFL) + 1
NFL : FREELISTS定义的Process free list个数
2.3.3 Transaction Free Lists
当Oracle需要时动态创建。一个Transaction Free List 是一种专门给某一个事务使用的free list. 每个段至少有16个transactions free lists, 并且这个值在需要时会增长,直到达到Segment Header块的大小限制。一个事务只有下面情况下会需要分配一个Tx Free Lists entry: 块中释放空间时(DELETE or UPDATE) 并且还不存在Tx Free Lists entry时。
2.4 Free list行为2.4.1 Freelist Link and Unlink 操作
Freelist 按后进先出队列(LIFO) 方式管理。也就是说最后被link到freelist的块拥有最先unlink的机会。
当块中空闲空间增加到大于PCTFREE时,块放入freelist中。free list中的块可用来作update 或insert。 当块中没有足够的空间用于insert操作时并且使用空间大于PCTUSED,块就会从free list中移出。
在块在DELETE or UPDATE 操作之后,如果使用空间落到PCTUSED下,块再次link到free list中。每次块加入free list时,都是link到链表的头部。
例如:考虑段中有120个块编号由1到120。其中有6个块在free list上并假设HWM是 80。(block实际使用DBA编号)
10->24->45->46->65->80-|
现在作INSERT 操作,需要400 bytes空间。假设块10上空间不足,但块24上空间可用。现在数据插入到块 24 ,现在块24的剩余空间小于该表的PCTUSED。因此块 24 从free list链表中移出。PCTFREE and PCTUSED参数的目的就是用来控制数据块从free list的链表中移入/移出行为的。现在free lists象这样:
10->45->46->65->80-|
然后在同一事务中作DELETE同一个段的数据,使块 54 和 67落到PCTUSED下。现在这些块加入到free list链中。free list链现在象这样:
67->54->10->45->46->65->80-|
2.4.2 Transaction Free List 算法
扫描segment Header块中所有的Tx free list,检查是否还没有Tx free list entry分配给transaction, 如何没有,将寻找未使用的entry或已经提交了事务的空的Tx free list。如果上述搜索过程失败, 新的entry会在segment Header块中Tx free lists区域中开辟。如果没有空间来生成, 事务就必须等待entry的释放。
segment header中的最大free list个数:
Block Size Max # Freelists
----------- -----------------
2K 24
4K 50
8K 101
16k 204
事务T1释放出来的空闲块(DELETE or UPDATE)的使用 :
l 立即被T1所重用
l 当T1 commit后被其它需要空闲块的事务重用,过程举例如下:
2.5 HMW概念
HIGH WATER MARK代表一个表使用的最大的(top limit)块 。2.1中已经提到HIGH WATER MARK 记录在segment header中,并且在Oracle插入数据时一般增长5个blocks(并非总是5个块,具体参见2.4.2中流程图中HMW增长方式)。
segment header block中与HWM相关信息说明如下:
EXTENT CONTROL:
Extent Header:: spare1: 0 space2: 0 #extents: 13 #blocks: 1429
last map 0x00000000 #maps: 0 offset: 4128
Highwater:: 0x04d0 ext#: 12 blk#: 275 ext size: 475
#blocks in seg. hdr's freelists: 5
#blocks below: 1229
mapblk 0x00000000 offset: 12
Unlocked
==> spare1: this field is no longer used (old inc#, now always 0)
==> space2: this field is no longer used (old ts#, now always 0)
==> #extents: number of extents allocated to segment
==> #blocks: number of blocks allocated to segment
==> last map: address of last extent map block
0 if extent map is entirely in the segment header
==> #maps: number of extent map block
==> offset: offset to end of extent map
==> HWM dba: address of block at highwater mark
==> ext#: HWM extent number relative to segment
==> blk#: HWM block number within extent
==> ext size: HWM extent size (in blocks)
==> #blocks in seg. hdr's freelists: number of blocks in seg. hdr's free list
==> #blocks below: number of blocks below HWM
==> mapblk dba: dba of extent map block containing HWM extent
is 0 if HWM is in the segment header
==> offset: offset within extent map block
is the ext# if HWM is in segment header
==> Locked by: if locked by a transaction, the xid is displayed
HWM可以说是已经使用过的存储空间和未使用过的存储空间之间的分界线。在表使用过程中,HWM一直向一个方向移动,插入记录时HWM可能会向增加的方向移动,但是删除记录时HWM并不会向相反的方向移动。参见2.4.2。下图显示了某个数据段中HWM的位置情况。
图2.5
HIGH WATER MARK之所以重要是因为它对全表扫描性能的影响,
当实施一个全表扫描时,Oracle会读取所有HIGH WATER MARK下的块即使它们是空块。当HIGH WATER MARK 下有很多unused block时实施全表扫描会增加额外的不必要的I/O。它也会在全局共享区中填充很多很多空块。
3.分析方法
存储参数基本上属于oracle internal的东西,因此oralce并没有提供很好的手段来分析。但是对于DBA来说,还是可以通过block dump和DBMS_SPACE等手段来获取部分信息。
3.1 提取block和free list信息
创建dbms_space使用的存储过程show_space
SQL>
create or replace procedure show_space
( p_segname in varchar2,
p_owner in varchar2 default user,
p_type in varchar2 default 'TABLE',
p_partition in varchar2 default NULL )
as
l_free_blks number;
l_total_blocks number;
l_total_bytes number;
l_unused_blocks number;
l_unused_bytes number;
l_LastUsedExtFileId number;
l_LastUsedExtBlockId number;
l_last_used_block number;
procedure p( p_label in varchar2, p_num in number )
is
begin
dbms_output.put_line( rpad(p_label,40,'.') || p_num );
end;
begin
dbms_space.free_blocks
( segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
partition_name => p_partition,
freelist_group_id => 0,
free_blks => l_free_blks );
dbms_space.unused_space
( segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
partition_name => p_partition,
total_blocks => l_total_blocks,
total_bytes => l_total_bytes,
unused_blocks => l_unused_blocks,
unused_bytes => l_unused_bytes,
last_used_extent_file_id => l_LastUsedExtFileId,
last_used_extent_block_id => l_LastUsedExtBlockId,
last_used_block => l_last_used_block );
p( 'Free Blocks', l_free_blks );
p( 'Total Blocks', l_total_blocks );
p( 'Total Bytes', l_total_bytes );
p( 'Unused Blocks', l_unused_blocks );
p( 'Unused Bytes', l_unused_bytes );
p( 'Last Used Ext FileId', l_LastUsedExtFileId );
p( 'Last Used Ext BlockId', l_LastUsedExtBlockId );
p( 'Last Used Block', l_last_used_block );
end;
过程已创建。
SQL> create table t1(a char(1000)) storage( freelists 3);
表已创建。
SQL> set serveroutput on;
SQL> exec show_space('T1');
Free Blocks.............................0 <==Number of blocks on freelist
Total Blocks............................5 <==Total data blocks in segment
Total Bytes.............................20480 <==Total bytes in segment
Unused Blocks...........................4 <==Total unused blocks in segment
Unused Bytes............................16384 <==Total unused bytes in segment
Last Used Ext FileId....................15 <==File id of last used extent
Last Used Ext BlockId...................562 <==Block id of last used extent
Last Used Block.........................1 <==Last used block in extent
PL/SQL 过程已成功完成。
有关show_space的进一步使用技巧可参考文献5。以下利用上面得到的数据对segment header block进行dump。
SQL>alter system dump datafile 15 block 562;
在udump/ora10792.trc中
*** -09-08 15:29:57.343
Start dump data blocks tsn: 27 file#: 15 minblk 562 maxblk 562
buffer tsn: 27 rdba: 0x03c00232 (15/562)
scn: 0x0000.064560e4 seq: 0x02 flg: 0x00 tail: 0x60e41002
frmt: 0x02 chkval: 0x0000 type: 0x10=DATA SEGMENT HEADER - UNLIMITED
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 space2: 0 #extents: 1 #blocks: 4
last map 0x00000000 #maps: 0 offset: 2080
Highwater:: 0x03c00233 ext#: 0 blk#: 0 ext size: 4
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Unlocked
Map Header:: next 0x00000000 #extents: 1 obj#: 60033 flag: 0x40000000
Extent Map
-----------------------------------------------------------------
0x03c00233 length: 4
nfl = 3, nfb = 1 typ = 1 nxf = 0
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
End dump data blocks tsn: 27 file#: 15 minblk 562 maxblk 562
对于上述块中字段的说明,以及相关试验。由于篇幅所限,本文不再列举。可参考文献7。
对非segment header的data block的dump方法和上述类似。data block的结构和segment header block不一样,如果需要了解,可查阅参考文献和资料。
3.2 提取HWM信息3.2.1 HWM位置
HWM位置按下面的公式计算:
HWM = useed byte = Total Bytes - Unused Blocks
Total Bytes和Unused Blocks都可以用show_space提取。
还可以通过ANALYZE tables得到HWM信息. DBA_TABLES视图中包含了可用于各表空间分析的列。其中blocks代表已使用过的块即HWM,empty_blocks代表未使用的空间。
3.2.1 HWM下空间利用信息
要比较有数据行的块的块数和HIGH WATER MARK下总块数,可以用下面的公式来展示HWM下未用空间的比例。
p = 1- r/h
r:有数据行的块的块数
h:HWM下的块数.
r可以通过如下方法获得:
Oracle7:
SELECT count(distinct substr(rowid, 15,4) || substr(rowid, 1,8) ) FROM schema.table;
Oracle8 and Oracle9:
SELECT count(distinct substr(rowid, 7,3) || substr(rowid, 10,6) ) FROM schema.table;
如果公式计算的结果 p是0,就不需要对表进行重建。如果结果p大于0,应该考虑系统状况和应用需要来决定是否需要总组表。
4.优化4.1手工回收存储空间
在HIGH WATER MARK以上的块对性能没有影响,但是会耗费空间。如何空间大小是一个考虑的问题,就可以决定回收空块。
假设表T1的存储示意图如图2.5所示,使用ALTER TABLE ... DEALLOCATE UNUSED语句可以回收HWM以上的空间。比如:
alter table t1 deallocate unused;
回收后T1的存储示意如图4.1.1
图4.1.1
如果在ALTER TABLE ... DEALLOCATE UNUSED语句中使用了KEEP关键字,则可以在HWM之后保留指定大小的空闲空间,比如:
alter table t1 deallocate unused keep 10K;
回收后T1的存储示意如图4.1.2
图4.1.2
4.2删减表
根据3.2.1可以得到HWM以下块的使用情况。如何p大于时,对全表扫描性能会产生影响,同时也会耗用空间。
如果能够确认应用有良好的索引几乎不会用到全表扫描,那么HIGH WATER MARK以下的空块,尽管耗费了空间,不会对访问产生影响。如果不能确定,那么就需要考虑删减表。
删减表的操作将删除表中所有的记录,并且重置HWM标记。表在删减之后将成为一个空表。
在Oracle中删减表只有如下的两种办法:
1.使用drop语句
先使用drop语句删除整个表,然后再重建这个表。在删除-重建的过程中,与表相关的所有索引、完整性约束以及触发器都会丢失,并且所有依赖于该表的对象都会变为INVALID状态,同时原来争对表的授权也会失效。因此采用这种方式删除表中的记录代价太大。
2.使用TRUNCATE语句
TRUNCATE语句属于DDL语句,不会产生任何回退信息,并且被立即自动提交。在执行TRUNCATE语句时不会影响到与被删减表相关的任何数据库对象与授权,也不会触发表中所定义的触发器。此外,在对标进行删减时,HWM将重置,已经为表分配的存储空间将被回收。
在执行TRUNCATE语句时,可以通过drop storage子句和reuse storage子句来控制被释放的区是否回收到表空间中。如何作在线系统的TRUNCATE,不希望表长时间锁住,那么可以使用reuse storage子句,仅将HWM重置。
4.3 free list优化
free list 竞争出现在多个进程使用同一个free list并试图同时修改free list头部数据块时。可以通过查询视图v$waitsate的class类型为data block 的记录来检查竞争情况。
产生data block类型竞争的主要原因是多个进程试图同时修改free list头部数据块。 然而,它也会出现在当进程准备将块读入buffer cathe时,另一个进程需要访问同一个块。如果能在V$SESSION_WAIT中正好捕获buffer busy waits,就可以通过查询V$SESSION_WAIT中的P3来判定是那一类。A 0 或 1014代表读类型,其他的值为修改竞争的类型。
下一步需要确定竞争涉及那些段。 如果能够在V$SESSION_WAIT捕获waits,就可以用P1和P2的值 (对应file 和 block) 在DBA_EXTENTS中找到段名。 如何是一个表,就很可能需要重建表来创建更多的process freelists。 一种计算需要创建多少个freelist的方法是dump一些段中接近HWM的块,检查interested transaction list的个数,具体方法可参见3.1。interested transactions个数的峰值加1 就是需要的最小process freelists的值。
从2.3和2.4可以看出,使用多个free list可能导致更多的空块未被使用, 也可能导致段更快地扩展。如果性能是当前所关心的重点,那么多free lists 可以用来提高并发访问能力,当然会增加一些额外空间的耗用。然而,如果空间使用大小是首先考虑的因素,那么推荐使用single freelist,使参数FREELISTS=1, 当然就不能提升并发事务的性能了。
V$WAITSTAT 也可显示其他类型class的竞争,包括segment header 和free list。 出现在同一个free list group中多个事务需要同时更新它们的free list header记录时。 有多种方法来解决这个问题如重建表采用更多的free list groups,或者增加 _bump_highwater_mark_count大小,或者调整应用本身。
参考文献和资料:
1.《FREELISTS and FREELIST GROUPS. SCOPE & APPLICATION 》
2.《INITRANS, MAXTRANS, FREELISTS and FREELIST GROUPS, PCTFREE and PCTUSED》,Mike Ault
3.《Freelist Internals: An OverviewKnowledge》,Xpert for Oracle Administration
4.《Blockdump - 8.x Data Segment Header in Oracle》
5.《AskTom dbms_space_free_space》,asktom.oracle.com
6.《Data Blocks and Freelists》,www.ixora.com.au
7.《偷窥Data block 的物理结构》,www.itpub.net
8.《Oracle 9i for windows nt/2000数据系统培训教程》,清华大学出版社
上述部分文章在我的blog网站blog.csdn.net/youbo2004上可找到,对于研究free list,free list group和block等有很好的帮助。
篇6:用智能优化限制提高Oracle数据库性能
Oracle SQL运行时间的最主要的组成部分是花在为执行准备新的SQL语句上的时间,不过,如果了解了可执行计划产生的内在机制,你就可以控制Oracle花费在评估表的连接顺序的时间,并在总体上提高查询的性能。
准备为执行提供的SQL语句
在一个SQL语句进入Oracle库的cache之后、而真正被执行之前,将会依次发生如下事件:
语法检查——检查该SQL语句的拼写和词序是否正确。
语义解析——Oracle根据数据词典(data dictionary)来验证所有的表格(table)和列(column)。
已保存纲要检查——Oracle检查词典以确认对应该SQL语句是否已存在已保存的纲要(Stored Outline)。
产生执行计划——Oracle根据一种罚值(cost-based)优化算法和数据词典中的统计数据来决定如何生成最优执行计划。
产生二进制代码——Oracle在执行计划的基础上生成可执行的二进制代码。
一旦开始准备执行SQL语句,上述的过程很快就会执行,这是因为Oracle可以识别出同样的SQL语句并对同样的SQL语句重复使用对应的可执行代码。然而,对产生ad hoc SQL的系统以及SQL中嵌入文本值(literal value)的情况,SQL执行计划的生成时间就会变得相当长,而且以前的执行计划也常常不能被再次利用。对那些牵涉到许多表格的查询,Oracle可能要花上很长的时间来决定把连接这些表格的顺序。
评估连接表格的顺序
生成可执行计划的时间往往是SQL的准备过程中最大的开销组成部分,尤其是在处理有多个表的连接的查询的情况下。当Oracle评估表的连接顺序时,它必须考虑每一种可能的排序。例如,当有六个表格需要连接时,Oracle需要考虑720种(6的排列数,即6×5×4×3×2×1=720)可能的连接排序。当需要连接的表的数量超过10时,这个排列问题将变得非常突出:如果需要连接的表格有15个,那么需要考虑的可能的查询排列顺序超过一万亿种(精确值为1,307,674,368,000)。
在optimizer_search_limit参数中设置限制
你可以通过optimizer_search_limit参数来控制上述问题的发生,该参数用来指定优化器评估的表格连接顺序的最大数目。利用这个参数,就可以防止优化器在评估所有可能的表格连接顺序中所花费的多余时间。如果查询中的表的数量少于或者等于optimizer_search_limit,那么优化器检查所有的可能表的连接方式。
例如,涉及了五个表的查询一共有120种(5!=5×4×3×2×1=120)可能的连接顺序,所以如果参数optimizer_search_limit的值设置为5(默认值),那么优化器就会考虑所有的这120种可能的连接顺序。optimizer_search_limit参数还用来控制启动开始连接指示(star join hint)的阈值。当查询所涉及的表格数量少于参数optimizer_search_limit的设定值,开始连接指示将被设置。
另一个工具:optimizer_max_permutations参数
optimizer_max_permutations初始参数用来设定优化器优化范围的上界(即最多考虑多少种表格连接顺序),它依赖于初始参数optimizer_search_limit。参数optimizer_max_permutations的默认值为8000。
参数optimizer_search_limit 和optimizer_max_permutations一同用来设置优化器所考虑的排列数的上限,
优化器不断的产生可能的表的连接的排列,直到排列数达到参数optimizer_search_limit或者optimizer_max_permutations为止。一旦优化器停止产生新的可能连接排列,它将会从中选择出耗费最小的排列。
用已排序指示来指定一种连接排序
你可以设定优化器评估的排列数的上限。但是对复杂的情况下,即使允许的排列数很大,优化器也很可能在远远没有找到一个比较合适的排列之间就已经停止优化了。你不妨回头看看我前面举的那个例子(15个需要连接的表有超过一万亿种排列)。如果设定优化器考虑80,000种排列,那么这仅仅考虑了所有可能性的0.000006%,优化器极可能没有达到最佳的排列。
在Oracle SQL中解决这个问题的最好方法就是手工指定一种表格连接顺序。这里需要遵循的大原则就是表格连接顺序应该使得查询计划尽快得以建立,通常在SQL语句中使用WHERE限制子句。
下面以一个对名为emp的表格的并行查询为例,例子中的代码强制查询计划执行一个嵌套循环连接(nested loop join)。注意,我使用了已排序指示来引导优化器来评估WHERE子句中给出的表格的连接顺序。 select /*+ ordered use_nl(bonus) parallel(e, 4) */
e.ename,
hiredate,
b.comm.
from
emp e,
bonus b
where
e.ename = b.ename
;
上面的例子要求优化器按照SQL语句中FROM子句指定的顺序连接表格,FROM子句中第一个的表格指定为驱动表格(driving table)。已排序指示常常与其它指示联合使用以确保多个表格按照适当的顺序连接起来。在遇到涉及四个以上表格的数据仓库查询时常常也是这样处理。
下面另给出一个例子,在这个例子中,我们使用一个已排序指示(ordered hint)来把表格按照一个特定的顺序(先是emp,然后是dep和sal,最后是bonus)连接起来。进一步改进执行计划,我指定emp表格到dept表格的连接使用hash连接,sal表格到bonus表格使用嵌套循环连接。 select /*+ ordered use_hash (emp, dept) use_nl (sal, bonus) */
from
emp,
dept,
sal,
bonus
where . . .
对实际应用的建议
在实际应用场合下,减小optimizer_max_permutations参数并使用已保存的优化计划或者已保存纲要(这样在查询涉及到许多表格时,就可以避免重新解析查询所花费的实际)会更有效率。一旦找到最好的表格连接顺序,你可以手工指定表格的连接顺序(通过已排序指示)并保存纲要,这样就永久保存该表格连接顺序。
当执行一个新的查询时,你可以首先把optimizer_search_limit设置为该查询所涉及的表格数,这样优化器将从所有的连接顺序中找出最佳的那种。以后执行该查询时,你就可以在WHERE子句中按照最佳连接顺序排列表格名称,并设置已保存指示和已保存纲要,这样就可以按照最佳顺序连接表格而无需重复评估各种可能排序。这样查询的速度将会得到显著的提高。
已排序指示的优先级高于optimizer_search_limit和 optimizer_max_permutations参数。如果设置了已排序指示,那么表格就会按照查询命令中的FROM子句给出的顺序连接,这样这个过程就没有优化器优化表格的连接顺序这一步骤了。
作为Oracle的专业人士,你应该知道SQL语句进入库cache中有一个明显的起始延时。但是聪明的Oracle数据库管理员以及Oracle开发者能改变表格的搜索限制参数或者利用已排序指示来手工指定表格的连接顺序,这样可以极大的降低优化以及执行新查询所花费的时间。
篇7:不要让临时表空间影响Oracle数据库性能数据库教程
在Oracle数据库中进行排序、分组汇总、索引等到作时,会产生很多的临时数据,如有一张员工信息表,数据库中是安装记录建立的时间来保存的。如果用户查询时,使用Order BY排序语句指定按员工编号来排序,那么排序后产生的所有记录就是临时数据。对于这些临时数据,Oracle数据库是如何处理的呢?
通常情况下,Oracle数据库会先将这些临时数据存放到内存的PGA(程序全局区)内。在这个程序全局区中有一个叫做排序区的地方,专门用来存放这些因为排序操作而产生的临时数据。但是这个分区的容量是有限的。当这个分区的大小不足以容纳排序后所产生的记录时,数据库系统就会将临时数据存放到临时表空间中。这就是临时表空间的来历。看起来好像这个临时表空间是个临时工,对于数据库的影响不会有多大。其实大家这是误解这个临时表空间了。在用户进行数据库操作时,排序、分组汇总、索引这些作业是少不了,其会产生大量的临时数据。为此基本上每个数据库都需要用到临时表空间。而如果这个临时表空间设置不当的话,则会给数据库性能带来很大的负面影响。为此管理员在维护这个临时表空间的时候,不能够掉以轻心。要避免因为临时表空间设置不当影响数据库的性能。具体来说,主要需要注意如下几个方面的内容。
一、创建用户时要记得为用户创建临时表空间。
最好在创建用户时为用户指定临时表空间。如可以利用语句default temporary table space语句来为数据库设置默认的临时表空间。不过在Oracle数据库中这个不是强制的。但是笔者强烈建议这么做。因为如果没有为用户指定默认临时表空间的话,那么当这个用户因为排序等操作需要使用到临时表空间的话,数据库系统就会“自作聪明”的利用系统表空间SYSTEM来创建临时段。众所周知,这是一个系统表空间。由于在这个表空间中存放着系统运行相关的数据,一般的建议是用户的数据不能够保存在这个表空间中。那么如果将用户的临时表空间防止在这个系统表空间之内,会产生什么负面影响呢?
由于临时表空间中的数据是临时的。为此数据库系统需要频繁的分配和释放临时段。这些频繁的操作会在系统表空间中产生大量的存储碎片。当这些存储碎片比较多时,就会影响系统读取硬盘的效率,从而影响数据库的性能。其次系统表空间的大小往往是有限制的。此时临时段也来插一脚,就会占用系统表空间的大小。
为此数据库管理员需要注意一点,当没有为用户指定临时表空间时,用户排序等操作仍然需要用到临时段。此时数据库系统就会将临时段放入到系统表空间中。为此就会对数据库的性能产生不利的影响。所以笔者建议各位读者与数据库管理员,在创建用户的时候同时为用户指定一个默认的表空间,以减少临时段对系统表空间的占用。
二、合理设置PGA,减少临时表空间使用的几率。
当排序操作产生临时数据时,数据库并不是马上将其存储在临时表空间中。通常情况下,会先将这些临时数据存储在内存的PGA程序全局区内。只有当这个程序全局区无法容纳全部数据时,数据库系统才会启用临时表空间中的临时段来保存这些数据。但是众所周知,操作系统从内存中读取数据要比从硬盘中读取数据块几千倍。为此比较理想的情况是,这个程序全局区足够的大,可以容纳所有的临时数据。此时数据库系统就永远用不到临时表空间了,
从而可以提高数据库的性能。
但是这毕竟只是一个理想。由于内存大小等多方面的限制,这个PGA程序区的大小往往是有限制的。所以在进行一些大型的排序操作时,这个临时表空间仍然少不了。现在数据库管理员可以做的就是合理设置这个PGA程序全局区的大小,尽量减少临时表空间使用的几率。如在实际工作中,数据库管理员可以根据需要来设置初始化参数SORT_AREA_SIZE参数。这个参数主要控制这个PGA程序全局区内排序区的大小。通常情况下,如果这个数据库系统主要用来查询并且需要大量的排序、分组汇总、索引等操作时,那么可以适当调整这个参数,来扩大PGA分区的大小。相反,如果这个系统主要用于更新操作,或者在这个数据库服务器上还部署由其他的应用程序,那么这个PGA分区就不能够占用太多的内存,以防止对其他应用程序产生不利的影响。所以说,数据库官员不能够一刀切,需要根据实际情况来调整。在必要的情况下,可以增加系统内存来增加PGA分区的大小,从而降低临时表空间的使用几率,以提高数据库的排序、分组汇总等操作的性能。
总之,如果临时段被频繁使用的话,由于内存与硬盘在性能上的差异,从而会降低数据库的性能。为此在平时工作中,数据库管理员还需要监控临时表空间的使用情况,以判断是否需要采取措施来减少临时表空间的使用来提高数据库的查询性能。为了实现这个目的,笔者建议数据库管理员可以查看v0_segment这张动态性能视图。通过这张动态性能视图可以查看系统排序段(临时段的一种)的使用情况。另外通过动态性能视图v0_usage还可以查询使用排序段的用户与会话信息。从而为数据库管理员优化数据库性能提供数据上的支持。对于这个排序段,笔者还要说明一点。对于排序段来说,同一个例程的所有SQL语句(如果需要排序操作的话)都将共享同一个排序段。并且排序段在第一次需要用到时被创建。排序完成后这个排序段不会被释放,只有在这个历程关闭后排序段才会被释放。为此以上两张视图要综合起来分析,才能够得到数据库管理员想要的信息。
三、要为临时表空间保留足够的硬盘空间。
其他表空间对应的数据文件,在其创建时就会被完全分配和初始化,即在其创建时就会被分配存储空间。但是临时表空间对应的临时文件则不同。如在Linux操作系统中,临时表空间创建时系统是不会分配和初始化临时文件的。也就是说,不会为临时文件分配存储空间。只有临时数据出现需要用到临时文件的时候,系统才会在硬盘上分配一块地方用来保存临时文件。此时就可能会产生一个问题,即当需要用到临时文件系统为其分配空间的时候,才会先系统分区中没有足够的存储空间了。此时就会产生一些难以预料的后果。
为此对于这些临时文件,数据库管理员最好能够预先为其保留足够的空间。如在Linux操作系统中,可以将其防止在一个独立的分区内,不允许其他应用程序使用。如此的话,就不用担心临时文件没有地方存储了。另外由于临时表空间主要用来存放一些排序用的临时文件。为此如果能够将这个临时表空间存放在性能比较好的分区中,还可以提高数据库系统读取临时表空间中数据的速度。另外由于系统需要频繁分配临时表空间中的数据,为此临时表空间所在的分区会出现比较多的碎片。此时如果将临时表空间存放在一个独立的分区内,那么数据库管理员就可以单独对这个分区进行碎片整理,从而提高这个分区的性能。所以无论出于什么原因,将临时表空间防止在一个独立的分区内,是一个不错的想法。不仅可以保证临时文件有存储的空间,而且还可以提高数据库的性能。
对于临时表空间最后需要说明的是,默认情况下这个临时表空间对各个用户都是共享的。也就是说每个连接到数据库的用户都可以使用默认的临时表空间。数据库管理员可以为其指定其他的临时表空间。一般来说,只需要一个临时表空间即可
篇8:IBM Viper让SAP看到反击Oracle的希望数据库教程
SAP选择IBM的Viper作为其中小用户的数据库
两公司强化它们共同对战Oracle的战线
IBM和SAP AG 本月中旬联合宣称,IBM的下一代DB2数据库将被SAP的中小型企业用户软件优选为数据库软件,此举意为强化它们的战线以共同应对其共同的对手Oracle,
选择购买套装mySAP ERP软件的用户可以得到DB2 Viper,Viper预计在夏季上市。据IBM的市场部主管Bernie Spang称,Viper将具有出色的性能表现。
Spang称,在去年IBM和SAP联手为所有SAP应用推出一款特制的DB2版本后,“数以百计”的SAP用户或者从Oracle 数据库转向使用DB2,或者在选择新的SAP产品时选择DB2而非Oracle产品。 但是他拒绝给出更多的细节。
Spang说:“现在,我们将压力转到了Oracle一方。相信这将为DB2带来数以千计的新用户。”
但是,一名分析人世指出,SAP捆绑DB2其实从2001年就已经开始了,而其效果并不显著。RedMonk Inc的分析师James Governor说:“我对这个翻新的注意是否能成功持怀疑态度。”
“用户并没有表现出将Oracle驱出数据库领域的强烈愿望。SAP和IBM可能从Oracle方面赢得了一些客户,但是到目前为止,这看上去更像是正常的客户流动而不是大规模的放弃…目前,赢家似乎是那些拒绝被迫作出可能会后悔的决定的用户,
“
除了那些考虑从Unix系统转向廉价的基于Linux系统软件的用户,IBM和SAP还瞄准了Siebel、PeopleSoft或是J.D. Edwards software的用户。这些公司在近年来被Oracle收购,IBM和SAP希望能抓住一些希望变化的客户,尽管Oracle已经作出保证,它们将继续运行非Oracle的中间件或数据库。
一名在Unix上运行SAP和Oracle数据库的数据库管理员说,这条消息可能会促使她的公司“在近期“转而使用DB2。
她说:“我们使用的Oracle运行良好,我们的人员对目前的设置十分熟练并具有经验。”她的雇员曾经将数据仓库从Oracle数据库转变为DB2 Universal Database。这一变化节省了开支,并且DB2表现可靠,并有优秀的厂商支持。”但这也影响到了一些IT员工。
她说:“如果DB2的价格明显低于Oracle,我们将会更仔细地考虑。但是我们还要考虑到再培训我们员工以及雇佣承包人等的费用。”
Spang没有透露软件包的价格,客户可以从SAP或其渠道合作者处购买,它们还将提供支持。得到最新版本DB2 mySAP All-In-One的新用户可以享受一年的免费维护。
今天的发布是在下周在Orlando的Sap用户大会Sapphire 2006召开前作出的。
★临时表在Oracle数据库与SQL Server数据库中的异同
文档为doc格式