zoukankan      html  css  js  c++  java
  • HWM的实验

    HWM是数据段中使用空间和未使用空间之间的界限,假如现有自由链表上的数据块不能满足需求,Oracle把HWM指向的数据块加入到自由链表上,HWM向前移动到下一个数据块。简单说,一个数据段中,HWM左边是使用的数据块,右边是目前还没有被使用的数据块。

    一个表在表空间中创建以后,会先分配一些初始的数据区。随着表中行数的增加,区也会相应的扩展,DBA_SEGMENTS试图的BLOCKS和EXTENTS列记录了相应的数据区块的信息。

    SQL> create table test(id number);

    Table created.

    SQL> select blocks, extents from dba_segments where segment_name='TEST' and owner='HR';

    BLOCKS EXTENTS
    ---------- ----------
    8 1

    现在对表进行分析,以查看HWM。

    SQL> analyze table test compute statistics;

    Table analyzed.

    SQL> select blocks, empty_blocks, num_rows from dba_tables where table_name='TEST' and wner='HR';

    BLOCKS EMPTY_BLOCKS NUM_ROWS
    ---------- ------------ ----------
    0 8 0

    现在我们往表中插入一些数据,再来查看HWM。

    SQL> insert into test select object_id from user_objects;

    142 rows created.

    SQL> commit;

    Commit complete.

    SQL> analyze table test compute statistics;

    Table analyzed.

    SQL> select blocks, empty_blocks, num_rows from dba_tables where table_name='TEST' and wner='HR';

    BLOCKS EMPTY_BLOCKS NUM_ROWS
    ---------- ------------ ----------
    5 3 142

    可以看出此时的HWM应该在blocks=6的位置,虽然这里分配了5个数据块,但数据不一定占据了5个块的位置。

    要想获取该表使用的确切的数据块,可以使用下面的查询。

    SQL> select count(distinct dbms_rowid.rowid_block_number(rowid)||'-'||
    dbms_rowid.rowid_relative_fno(rowid)) used_blocks
    from test;

    used blocks
    -----------
    1

    从这里可以看出test表占用了8个数据块,有5个被格式化以准备接收数据,但实际存储数据的只有一个数据块。

    我们把这几个块导出来查看一下。

    SQL> select distinct dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid) from test;

    DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
    ------------------------------------ ------------------------------------
    4 4348

    SQL> alter system dump datafile 4 block min 4348 block max 4350;

    System altered.

    相应的trace文件中,可以发现下面的信息。

    data_block_dump,data header at 0xeb19464
    ===============
    tsiz: 0x1f98
    hsiz: 0x12e
    pbl: 0x0eb19464
    bdba: 0x010010fc
    76543210
    flag=--------
    ntab=1
    nrow=142

    ......

    data_block_dump,data header at 0xeb19464
    ===============
    tsiz: 0x1f98
    hsiz: 0xe
    pbl: 0x0eb19464
    bdba: 0x010010fe
    76543210
    flag=--------
    ntab=0
    nrow=0

    可以看到,142行只存在于 bdba: 0x010010fc 这个块中,也就是datafile=4,block=4348的数据块。

    说到HWM就不能不提如何的降低一个表的HWM,因为如果一个表插入了大量的数据然后又被删除其中的一部分,表的HWM是不会下降的。在全表扫描的时候仍然会扫描到HWM的位置,这样必然导致IO资源的浪费。

    删除记录不会降低HWM,因此,删除记录不会导致EMPTY_BLOCKS块的增加,即使使用'alter table test deallocate unused;'命令也不行。改变表的HWM可以使用truncate table test;和alter table test move tablespace xxx;等方法。当然,10g中也可以使用alter table test shrink space;。

    现在使用具体的实例来说明各种方法对HWM的影响。

    首先采用移动表空间的方法。

    SQL> create table t(a number, b number, c number, d number, e number, f number);

    Table created.

    SQL> create or replace procedure populate (numrows in number) is
    fa number; fb number; fc number; fd number; fe number; ff number;
    begin
    dbms_random.Initialize(1234567);
    for i in 1..numrows loop
    fa:=mod(abs(dbms_random.random),10)+1991;
    fb:=mod(abs(dbms_random.random),2);
    fc:=mod(abs(dbms_random.random),20);
    fd:=mod(abs(dbms_random.random),30);
    fe:=mod(abs(dbms_random.random),40);
    ff:=mod(abs(dbms_random.random),10);
    insert into t values(fa,fb,fc,fd,fe,ff);
    if mod(i,100)=0 then commit; end if;
    end loop;
    dbms_random.Terminate;
    end;
    /

    Procedure created.

    SQL> set serveroutput on
    SQL> execute populate(200000);

    PL/SQL procedure successfully completed.

    SQL> delete from t where a=1991 and b=0;

    9991 rows deleted.

    SQL> commit;

    Commit complete.

    SQL> delete from t where f=9;

    13911 rows deleted.

    SQL> analyze table t compute statistics;

    Table analyzed.

    SQL> select num_rows,blocks,empty_blocks from dba_tables where table_name='T';

    NUM_ROWS BLOCKS EMPTY_BLOCKS
    ---------- ---------- ------------
    171270 684 84

    SQL> alter table t move tablespace users;

    Table altered.

    SQL> select num_rows,blocks,empty_blocks from dba_tables where table_name='T';

    NUM_ROWS BLOCKS EMPTY_BLOCKS
    ---------- ---------- ------------
    171270 684 84

    SQL> analyze table t compute statistics;

    Table analyzed.

    SQL> select num_rows,blocks,empty_blocks from dba_tables where table_name='T';

    NUM_ROWS BLOCKS EMPTY_BLOCKS
    ---------- ---------- ------------
    171270 569 71

    可以看到,重新分析后,表的HWM下降了。说明移动表空间的方法是可以降低HWM的,即使移动前后的表空间是相同的。

    接下来,再来看看export/import对HWM的影响。

    首先导出T表中的所有数据,

    $ exp hr/hr tables='t'

    ......
    About to export specified tables via Conventional Path ...
    . . exporting table T 171270 rows exported

    SQL> delete from t;

    171270 rows deleted.

    SQL> commit;

    Commit complete.

    SQL> analyze table t compute statistics;

    Table analyzed.

    SQL> select num_rows, blocks, empty_blocks from dba_tables where table_name='T';

    NUM_ROWS BLOCKS EMPTY_BLOCKS
    ---------- ---------- ------------
    0 569 71 --虽然行数变了,但是HWM仍然没有改变

    $ imp hr/hr ignore=y file=expdat.dmp full=y

    ......

    . importing HR's objects into HR
    . . importing table "T" 171270 rows imported

    SQL> analyze table t compute statistics;

    Table analyzed.

    SQL> select num_rows, blocks, empty_blocks from dba_tables where table_name='T';

    NUM_ROWS BLOCKS EMPTY_BLOCKS
    ---------- ---------- ------------
    171270 569 71

    可以看出import之后,表的HWM没有改变。

  • 相关阅读:
    Feign原理 (图解)
    纠错:Feign 没用 短连接
    【转】linux 查看哪些进程用了swap
    【转】交换分区SWAP
    【改】linux中分区的概念
    【转】SPI FLASH与NOR FLASH的区别 详解SPI FLASH与NOR FLASH的不一样
    【转】DDR3和eMMC区别
    ARP (地址解析协议)
    【转】一文搞懂C语言回调函数
    【改】shell 判断文件中有无特定子串方法(grep)
  • 原文地址:https://www.cnblogs.com/hllnj2008/p/4785522.html
Copyright © 2011-2022 走看看