oracle hwm 查询,oracle HWM

Oracle表段中的高水位线HWM :

在Oracle数据的存储中,可以把存储空间想象为一个水库,数据想象为水库中的水。

水库中的水的位置有一条线叫做水位线,在Oracle中,这条线被称为高水位线(High-warter mark,

HWM)。

在数据库表刚建立的时候,由于没有任何数据,所以这个时候水位线是空的,也就是说HWM为最低值

。当插入了数据以后,高水位线就会上涨,但是这里也有一个特性,就是如果你采用delete语句删

除数据的话,数据虽然被删除了,但是高水位线却没有降低,还是你刚才删除数据以前那么高的水

位。也就是说,这条高水位线在日常的增删操作中只会上涨,不会下跌。HWM通常增长的幅度为一次

5个数据块.

Select语句会对表中的数据进行一次扫描,但是究竟扫描多少数据存储块呢,这个并不是说数据库

中有多少数据,Oracle就扫描这么大的数据块,而是Oracle会扫描高水位线以下的数据块。

理解高水位的作用:理解全表扫描的开销(实验:如果)

@@@@@@

修正ORACLE表的高水位线

ORACLE中,执行对表的删除操作不会降低该表的高水位线。而全表扫描将始终读取一个段(extent)

中所有低于高水位线标记的块。如果在执行删除操作后不降低高水位线标记,则将导致查询语句的

性能低下。rebuild, truncate, shrink,move等操作会降低高水位。

A、执行表重建指令 altertabletable_namemove;(把楼移到另一块地)

B、 执行altertabletable_name shrinkspace; 此命令为Oracle 10g新增功能,再执行该指令之

前必须允许行移动 altertabletable_name enable row movement;

C、 重建表

复制要保留的数据到临时表t,drop原表,然后rename临时表t为原表

D、 用逻辑导入导出: Emp/Imp

E、. Altertabletable_namedeallocateunused

DEALLOCATEUNUSED为释放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> createtablett (id number);此时表没有分析,是原始的数据,即8个数据块。

SQL> selectsegment_name,segment_type,blocksfromdba_segmentswheresegment_nam

e='TT';

SEGMENT_NAME

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

SEGMENT_TYPE           BLOCK

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

TT

TABLE8(段占用了多少个块)

SQL> selecttable_name,num_rows,blocks,empty_blocksfromuser_tableswheretable

_name='TT';

TABLE_NAME                       NUM_ROWS     BLOCKS EMPTY_BLOCKS

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

TT

declare

i number;

begin

foriin1..10000 loop

insertintottvalues(i);

endloop;

commit;

end;

/

SQL>  SELECTsegment_name,segment_type,blocksFROMdba_segmentsWHERE

segment_name='TT';

SEGMENT_NAME    SEGMENT_TYPE        BLOCKS

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

TT              TABLE24

注释:user_dbasegments中的BLOCKS 列代表该表中曾经使用过得数据库块的数目

dba_dbasegments中的BLOCKS 列代表段占用多少个块

SQL> SELECTtable_name,num_rows,blocks,empty_blocksFROMuser_tablesWHERE

table_name='TT';

TABLE_NAME        NUM_ROWS     BLOCKS EMPTY_BLOCKS

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

TT

此时表TT 占用的数据库已经是24个了。 但是user_tables 显示的信息还是为空。 因为没有做统计

分析。

execDBMS_STATS.GATHER_TABLE_STATS('SYS','TT');(收集统计信息)

SQL> execDBMS_STATS.GATHER_TABLE_STATS('SYS','TT');(收集统计信息)

PL/SQL 过程已成功完成。

SQL> SELECTtable_name,num_rows,blocks,empty_blocksFROMuser_tablesWHERE

table_name='TT';

TABLE_NAME        NUM_ROWS     BLOCKS EMPTY_BLOCKS

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

TT                   10000         20            0

此时user_tables 已经有了数据,显示的使用了20个数据块。 但是empty_blocks 还是为空。

这里要注意的地方。 这个字段只有使用analyze 收集统计信息之后才会有数据。

5) 使用analyze 收集统计信息

SQL> ANALYZE TABLETT COMPUTESTATISTICS;

Tableanalyzed.

SQL> SELECTtable_name,num_rows,blocks,empty_blocksFROMuser_tablesWHERE

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数据

看是否会影响他的段大小

deletefromtt;

commit

SQL>  SELECTsegment_name,segment_type,blocksFROMdba_segmentsWHERE

segment_name='TT';

SEGMENT_NAME    SEGMENT_TYPE        BLOCKS

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

TT              TABLE24

SQL>analyze tablett computestatistics;(算出高水位线在那一块)

SQL> selecttable_name,num_rows,blocks,empty_blocksfromuser_tableswheretable

_name='TT';(blocks为高水位线)

TABLE_NAME                       NUM_ROWS     BLOCKS EMPTY_BLOCKS

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

TT                                      0         20            3

这里我们可以证明了什么:高水位不受delete影响

SQL>insertintottselect*fromtt;(tt已经删除没有数据)

SQL> insertintottselectrownumfromdba_objects;

已创建50323行。

SQL>analyze tablett computestatistics;

SQL> selecttable_name,num_rows,blocks,empty_blocksfromuser_tableswheretable

_name='TT';(查看高水位线(blocks))大于20

TABLE_NAME                       NUM_ROWS     BLOCKS EMPTY_BLOCKS

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

TT                                  50323         79            0

这里我们可以证明了什么:高水位不受commit影响,只要有插入数据HWM就会增加

@@@@@

释放高水位(truncate)

SQL> truncatetablett;

表被截断。

SQL> ANALYZE TABLETT COMPUTESTATISTICS;

表已分析。

SQL> selectsegment_name,segment_type,blocksfromdba_segmentswheresegment_nam

e='TT';

SEGMENT_NAME

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

SEGMENT_TYPE           BLOCKS

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

TT

TABLE8(又回到原来的8)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值