高水位线

所有的 oracle 段都有一个在段内容纳数据的上限,我们把这个上限称为 "high water mark" HWM 。这个 HWM 是一个标记,用来说明已经有多少没有使用的数据块分配给这个 segment

 

  HWM 通常增长的幅度为一次 5 个数据块, 原则上 HWM 只会增大,不会缩小,即使将表中的数据全部删除, HWM 还是为原值,由于这个特点,使 HWM 很象一个水库的历史最高水位,这也就是 HWM 的原始含义,当然不能说一个水库没水了,就说该水库的历史最高水位为 0 。但是如果我们在表上使用了 truncate 命令,则该表的 HWM 会被重新置为 0

 

HWM 的一些特性

 

1 oracle HWM 来界定一个段中使用的块和未使用的块。

 

  当我们创建一个表 :A ,ORACLE 就会为这个对象分配一个段 . 在这个段中 , 即使我们未插入任何记录 , 也至少有一个区 (64bit, 也就是 8 个块 ) 被分配 , 第一个区的第一个块就称为段头 (SEGMENT HEADE), 段头中就储存了一些信息 , 基中 HWM 的信息就存储在此 . 此时 , 因为第一个区的第一块用于存储段头的一些信息 , 虽然没有存储任何实际的记录 , 但也算是被使用 , 此时 HWM 是位于第 2 个块 . 当我们不断插入数据到 A , 1 个块已经放不下后面新插入的数据 , 此时 ,ORACLE 将高水位之上的块用于存储新增数据 , 同时 ,HWM 本身也向上移 . 也就是说 , 当我们不断插入数据时 ,HWM 会不断上移 , 这样 , HWM 之下的 , 就表示使用过的块 ,HWM 之上的就表示已分配但从未使用过的块 .

 

扫描二维码关注公众号,回复: 1347122 查看本文章

2 HWM 在插入数据时 , 当现有空间不足而进行空间的扩展时会向上移 , 但删除数据时不会往下移 .

 

  这就好比是水库的水位 , 当涨水时 , 水位往上移 , 当水退出后 , 最高水位的痕迹还是清淅可见 .

 

  删除数据后便存在浪费的空间, ORACLE 不会释放空间以供其他对象使用,有一条简单的理由:由于空间是为新插入的行保留的,并且要适应现有行的增长。被占用的最高空间称为最高使用标记 (HWM)

 

3 HWM 的信息存储在段头当中 .

 

  HWM 本身的信息是储存在段头 . 在段空间是手工管理方式时 ,ORACLE 是通过 FREELIST( 一个单向链表 ) 来管理段内的空间分配 . 在段空间是自动管理方式时 (ASSM),ORACLE 是通过 BITMAP 来管理段内的空间分配 .

 

4 ORACLE 的全表扫描是读取高水位标记 (HWM) 以下的所有块

 

  当用户发出一个全表扫描时, ORACLE 始终必须从段一直扫描到 HWM ,即使它什么也没有发现。该任务延长了全表扫描的时间。

 

5 、如何查看 HWM

select blocks, empty_blocks from dba_tables where table_name='xxx' and owner='xx';

 

BLOCKS 列代表该表中曾经使用过得数据库块的数目,即水线。 EMPTY_BLOCKS 代表分配给该表,但是在水线以上的数据库块,即从来没有使用的数据块

 

查看 HWM 例子

create table STUDENT

(

  ID    NUMBER primary key ,

  CODE VARCHAR2 ( 10 ),

  NAME VARCHAR2 ( 50 )

);

 

创建表后查询

select blocks, empty_blocks from dba_tables where table_name= 'STUDENT' and owner= 'TEST' ;

发现 blocks empty_blocks 都为空

 

插入数据

insert into student values ( 1 , '0000000001' , ' 张飞 ' );

插入数据后查询

select blocks, empty_blocks from dba_tables where table_name= 'STUDENT' and owner= 'TEST' ;

发现 blocks empty_blocks 都为空

 

收集统计信息

exec DBMS_STATS.GATHER_TABLE_STATS(ownname=> 'TEST' , tabname=> 'STUDENT' ,estimate_percent=> 100 , degree => 1 , cascade => TRUE );

 

收集统计信息后查询

select blocks, empty_blocks from dba_tables where table_name= 'STUDENT' and owner= 'TEST' ;

发现 blocks 5 empty_blocks 0

 

要特别注意使用 analyze 命令而不是 dbms_stats 包。因为 dbms_stats 包只分析对 CBO 有帮助的统计信息,对于 space usage information 这些信息对 CBO 没有帮助,是不会统计的,所以要用 analyze

analyze table TEST.STUDENT compute statistics ; 

 

但其实真正的查看方式应该是通过 dump 来查看。具体做法如下:

a 、查找到该表 segment 的第一个数据块

select header_file , header_block from dba_segments where owner= 'TEST' and segment_name= 'STUDENT' ;  

     

HEADER_FILE HEADER_BLOCK  

----------- ------------  

5          51  

b dump 该数据块 找到 trace 文件

alter system dump datafile 5 block 51;

udump 文件夹中找到刚刚产生的 TRC 文件,打开就能看到详细信息。   

 

6. 如何降低HWM

 

a.  重建表

alter   table   STUDENT  move ;

move 后索引会失效,需要重建索引

alter index SYS_C005160 rebuild ;

再次分析表

analyze table TEST.STUDENT compute statistics ;

 

b.  Shrink

alter table STUDENT enable row movement ;

alter table STUDENT shrink space ;

再次分析表

analyze table TEST.STUDENT compute statistics ;

 

c.       Truncate

truncate table STUDENT;

再次分析表

analyze table TEST.STUDENT compute statistics ;

猜你喜欢

转载自zhuyuehua.iteye.com/blog/1693738