现在的位置: 首页 > 综合 > 正文

HWM和delete,drop,truncate的关系

2012年01月18日 ⁄ 综合 ⁄ 共 2295字 ⁄ 字号 评论关闭
HWM和delete,drop,truncate的关系
===========================================================

今天下午好好看了oracle中的HWM,也就是高水位线,高水位线是一个段内使用和未使用的数据块的分界线。

Select * from user_tables where table_name=’TEST03’

其中有blocksempty_blocksnum_rows其中的blocks也就是此表所占用的block数量,empty_blocks空的blocknum_rows数据行数。User_tablesblocks也就是HWM

User_segment数据字典视图:blocks就是此segment分配的blocks总数,header_block就是此段断头所在的数据块编号等。

HWM的信息存储在段头中,根据段空间自动管理中是用位图来管理段内的空间分配

Deletetruncatedrop和高水位线的关系

Delete

delete只是把删除了高水位线下的block内的数据,但是不会降低高水位线,空闲的数据块供以后数据插入使用,delete也不会回收表段的数据扩展,delete所作的只是更新了block的内的数据块,不会对segmentHWMextent改变。

Truncate

truncate table test02 drop storage 截断表,重置HWM,回收unusedblocktablespace中去供其余的对象使用

truncate的实质是:

truncate是新建一个segment然后与现有对象关联, truncate table tablename drop toragesegment中会新建segment,重构的initial大小的段,但是initial不一定是一个扩展的大小,很有可能是多个extent组成了initial段的大小。create table storage(initial 6M),此时oracle会为表段分配初始段initial大小6M,很有可能就是由多个extent组成的!

Truncateflashback

早上truncate一个table 然后flashck出错

flashback table test01 to timestamp to_timestamp('2011-9-13 17:00:00','yyyy-mm-dd hh24:mi:ss')

如果对table进行ddl操作,例如truncate然后再flashback,因为flashback利用的是放置在undo tablespace的回滚段,truncateddl没有走回滚段,所以无法闪回表,也就会报上述的表的定义已经更改,所以truncate也叫截断表,改变了表的“内部的一些东西”。

表内部零散blockstruncate

整理表内部的碎片,可以用truncate跟上reuse storage,重新导入/插入数据,由于重置了新的segment,所以也可以解决段的内部零散blocks

Drop

drop是直接删除数据字典中的表的信息,当然也不存在段的任何信息,HWM也就没有必要再提了。

(一般如果drop大的表时,先truncate然后再drop)

降低段的HWM

alter table test02 move会将hwm移动,但是在move时需要双倍的表空间,如果表上有索引需要alter index indexname rebuild

alter table test02 shrink space收缩表 降低HWM

alter table test02 shrink space compact收缩表,但是不会降低HWM

(还可以利用expimpsegment中去来改变HWM,觉得可以新建segment然后exp,imp到新的segment来改变HWM,是否其中还有别的方法。)

回收段内的unused数据扩展但是并不能降低HWM

使用alter table test02 deallocate unused会回收unused状态的extents,也就是会回收segment中高水位线以上的数据块,但是并不能改变segment中的高水位线。

HWM和全表扫描:

oracle的全表扫描是读取高水位线HWM一下的所有block,当用户直接路径插入行时,直接用append提示插入或sqlldr插入,数据块直接置于HWM之上,不再使用extents中得unused block

直接插入和HWM

insert /*+append*/ into test01 values(1,'am')

(使用append 而且alter table tablename nologging模式会大量减少日志,只产生少数undoappend减少了空间的搜索,产生redo减少) 所以append方式会比平常的insert快,这里具体redo undo后续还要实际实验。

 

SegmentHWM

create table test03 select * from test01 where 1<>1

即使此时test03中没有任何数据,但是oracle中还是分配一个extent也就是8 blocks给此段,刚好db_block_size8K的也就是64K给此表段,此高水位线blocks0,然后后续的dml操作会增加HWM,如果没有shrinkmove等操作,一般HWM都只会往上增,不会减少。

 

抱歉!评论已关闭.