oracle HWM

Oracle表段中的高水位线HWM :  在Oracle数据的存储中,能够把存储空间幻想为一个水库,数据幻想为水库中的水。  水库中的水的方位有一条线叫做水位线,在Oracle中,这条线被称为高水位线(High-warter mark,     HWM)。    在数据库表刚树立的时分,由于没有任何数据,所以这个时分水位线是空的,也就是说HWM为最低值    。当刺进了数据今后,高水位线就会上涨, http://www.fp1111.info/linked/20130305.do; 可是这里也有一个特性,就是若是你选用delete句子删    除数据的话,数据尽管被删去了,可是高水位线却没有下降,仍是你方才删去数据从前那么高的水    位。也就是说,这条高水位线在平常的增删操作中只会上涨,不会跌落。HWM一般添加的起伏为一次    5个数据块.      Select句子会对表中的数据进行一次扫描,可是终究扫描多少数据存储块呢,这个并不是说数据库    中有多少数据,Oracle就扫描这么大的数据块,而是Oracle会扫描高水位线以下的数据块。    了解高水位的效果:了解全表扫描的开支(试验:若是)      @@@@@@  批改ORACLE表的高水位线  ORACLE中,履行对表的删去操作不会下降该表的高水位线。而全表扫描将一直读取一个段(extent)    中一切低于高水位线符号的块。若是在履行删去操作后不下降高水位线符号,则将致使查询句子的    功用低下。rebuild, truncate, shrink,move  等操作会下降高水位。    A、履行表重建指令 alter table table_name move;(把楼移到另一块地)  B、 履行alter table table_name shrink space; 此指令为Oracle 10g新增功用,再履行该指令之    前有必要答应行移动 alter table table_name enable row movement;    C、 重建表  仿制要保存的数据到暂时表t,drop原表,然后rename暂时表t为原表  D、 用逻辑导入导出: Emp/Imp  E、. Alter  table table_name deallocate unused    DEALLOCATE UNUSED为开释HWM上面的未运用空间,可是并不会开释HWM下面的自由空间,也不会移动    HWM的方位.   F、 引荐运用truncate.  @@@@@  ORACLE用HWM来界定一个段中运用的块和未运用的块.  举个比如来说,当咱们创立一个表时,ORACLE就会为这个目标分配一个段.在这个段中,即便咱们未插    入任何记载,也至少有一个区被分配,榜首个区的榜首个块就称为段头(SEGMENT HEADE),段头中就储    存了一些信息,其间HWM的信息就存储在此.此刻,由于榜首个区的榜首块用于存储段头的一些信息,虽    然没有存储任何实践的记载,但也算是被运用,此刻HWM是坐落第2个块.当咱们不断刺进数据到表后,    第1个块现已放不下后边新刺进的数据,此刻,ORACLE将高水位之上的块用于存储新增数据,一起,HWM    自身也向上移.也就是说,当咱们不断刺进数据时,HWM会往不断上移,这样,在HWM之下的,就表明运用    过的块,HWM之上的就表明已分配但从未运用过的块.    HWM在刺进数据时,当现有空间缺乏而进行空间的扩大时会向上移,但删去数据时不会往下移.  ORACLE 不会开释空间以供其他目标运用,有一条简略的理由:由于空间是为新刺进的行保存的,并    且要习惯现有行的添加。被占用的最高空间称为最高运用符号 (HWM),    @@@  ORACLE的全表扫描是读取高水位符号(HWM)以下的一切块.  @@@  啥样的刺进是在高水位上面进行刺进的?(append操作(不检查高水位线能否有数据,效率高,    不写日志,糟蹋空间))    当用直接途径刺进行时,即便HWM以下有闲暇的数据库块,键入在刺进数据时运用了append关键词,    则在刺进时运用HWM以上的数据块,此刻HWM会主动增大。     例如,经过直接加载刺进(用 APPEND 提示刺进)或经过 SQL*LOADER 直接途径 数据块直接置于     HWM 之上。它下面的空间就糟蹋掉了。    @@@@  关联测验:  SQL> create table tt (id number);此刻表没有剖析,是原始的数据,即8个数据块。    SQL> select segment_name,segment_type,blocks from dba_segments where segment_nam  e='TT';    SEGMENT_NAME  --------------------------------------------------------------------------------    SEGMENT_TYPE           BLOCK  ------------------ ----------  TT  TABLE                       8(段占用了多少个块)      SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table  _name='TT';    TABLE_NAME                       NUM_ROWS     BLOCKS EMPTY_BLOCKS  ------------------------------ ---------- ---------- ------------  TT      declare       i number;        begin        for i in 1..10000 loop        insert into tt values(i);        end loop;       commit;       end;        /      SQL>  SELECT segment_name,segment_type,blocks FROM dba_segments  WHERE     segment_name='TT';         SEGMENT_NAME    SEGMENT_TYPE        BLOCKS    --------------- --------------- ----------    TT              TABLE                   24    注释:user_dbasegments中的BLOCKS 列代表该表中从前运用过得数据库块的数目      dba_dbasegments中的BLOCKS 列代表段占用多少个块  SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables  WHERE     table_name='TT';      TABLE_NAME        NUM_ROWS     BLOCKS EMPTY_BLOCKS    --------------- ---------- ---------- ------------    TT        此刻表TT 占用的数据库现已是24个了。 可是user_tables 显现的信息仍是为空。 由于没有做计算    剖析。  exec DBMS_STATS.GATHER_TABLE_STATS('SYS','TT');(搜集计算信息)    SQL> exec DBMS_STATS.GATHER_TABLE_STATS('SYS','TT');(搜集计算信息)    PL/SQL 进程已成功完结。      SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables  WHERE     table_name='TT';         TABLE_NAME        NUM_ROWS     BLOCKS EMPTY_BLOCKS    --------------- ---------- ---------- ------------    TT                   10000         20            0         此刻user_tables 现已有了数据,显现的运用了20个数据块。 可是empty_blocks 仍是为空。   这里要注重的当地。 这个字段只需运用analyze 搜集计算信息之后才会有数据。        5) 运用analyze 搜集计算信息  SQL> ANALYZE TABLE TT COMPUTE STATISTICS;    Table analyzed.  SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables  WHERE     table_name='TT';         TABLE_NAME        NUM_ROWS     BLOCKS EMPTY_BLOCKS    --------------- ---------- ---------- ------------    TT                   10000         20            3    这个时分高水位在哪里呢?20(20 3=23<24) 这里有显现空的数据库有3个。    注重:20 3=23. 比占用的24个数据块少一个。由于有一个数据库块被保存用作segment header。      delete 数据  看能否会影响他的段巨细  delete from tt;  commit    SQL>  SELECT segment_name,segment_type,blocks FROM dba_segments  WHERE     segment_name='TT';         SEGMENT_NAME    SEGMENT_TYPE        BLOCKS    --------------- --------------- ----------    TT              TABLE                   24      SQL>analyze table tt compute statistics;(算出高水位线在那一块)      SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table  _name='TT';(blocks为高水位线)    TABLE_NAME                       NUM_ROWS     BLOCKS EMPTY_BLOCKS  ------------------------------ ---------- ---------- ------------  TT                                      0         20            3    这里咱们能够证明了啥:高水位不受delete 影响    SQL>insert into tt select * from tt;(tt现已删去没有数据)    SQL> insert into tt select rownum from dba_objects;    已创立50323行。    SQL>analyze table tt compute statistics;    SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table  _name='TT';(检查高水位线(blocks))大于20    TABLE_NAME                       NUM_ROWS     BLOCKS EMPTY_BLOCKS  ------------------------------ ---------- ---------- ------------  TT                                  50323         79            0  这里咱们能够证明了啥:高水位不受commit影响,只需有刺进数据HWM就会添加  @@@@@  开释高水位(truncate)    SQL> truncate table tt;    表被切断。    SQL> ANALYZE TABLE TT COMPUTE STATISTICS;    表已剖析。    SQL> select segment_name,segment_type,blocks from dba_segments where segment_nam  e='TT';    SEGMENT_NAME  --------------------------------------------------------------------------------    SEGMENT_TYPE           BLOCKS  ------------------ ----------  TT  TABLE                       8(又回到本来的8)    http://www.fpshamen.com/linked/20130305.do;

你可能感兴趣的:(oracle HWM)