概述

High-Water Mark,HWM是Segment的概念,如果我们把表想象成一张平面图在给表插入数据时由左至右开辟一系列块,高水位线就是曾经包含过数据的最右边的块,高水位线并不会随着数据的删除而降

high-water

HWM在全表扫描时会扫描HWM下的所有块,即使块中并不包含数据,这种扫描会严重性能。在一个手工管理(MSSM)的表空间中,每一个段只有一个HWM。在自动管理表空间(ASSM)中除了有HWM之外,在还有一个低HWM。在MSSM中,HWM向前推进(如INSERT)时,HWM之下所有的块都会被格式化并立即有效,Oracle可以安全读取这些块。在ASSM中,HWM推进时,Oracle并不会立即格式化所有块,而是在第一次使用这些块时才会完成格式化以便安全读取。

查看高水位

收集统计信息

ANALYZE TABLE  ESTIMATE/COMPUTE STATISTICS;
EXEC DBMS_STATS.GATHER_TABLE_STATS(<'USER'>,<'TABLE_NAME'>);

查看高水位

SELECT table_name,
                  ROUND ( (blocks * 8), 2) "High_Water(K)",
                  ROUND ( (num_rows * avg_row_len / 1024), 2) "USED_Space(K)",
                  ROUND ( (blocks * 10 / 100) * 8, 2) "Reserve_Space(K)",
                  ROUND (
                        ( blocks * 8
                          - (num_rows * avg_row_len / 1024)
                          - blocks * 8 * 10 / 100),
                        2)
                        "RECOVERY_Space(K)"
        FROM dba_tables
      WHERE temporary = 'N' and table_name='HIGHWATER'
ORDER BY 5 DESC;

修正高水位

重建表

ALTER TABLE TAB1 MOVE;

释放的空间只有自己才能使用,需重建索引。如果有LOB字段可以用:ALTER TABLE MOVE TABLESPACE LOB() STORE AS LOGSEGMENT TABLESPACE ;

临时表重建的方式

create table TAB2 as select * from TAB1;
drop table TAB1;
alter table TAB2 rename to TAB1;

SHRINK SPACE

ALTER TABLE TAB1 SHRINK SPACE;

10g新功能,需要先开启行迁移。10g中对cluster或带有LONG和LOB类型字段的表不起作用,不支持压缩表。与move的区别在于move是由segment底部开始的,移动数据到segment头部;shrink则是结合delete和insert,会产生大量的UNDO和REDO数据

EXPDP/IMPDP

通过数据泵导出再导入达到收缩高水位的目的

DEALLOCATE UNUSED

会释放HWM未使用的空间,不会移动HWM的位置

示例

SHRINK收缩

开启行迁移

ALTER TABLE … ENABLE ROW MOVEMENT;

收缩表(含索引)

ALTER TABLE … SHRINK SPACE [CASCADE|compact|null];

注:系统负载大时可以指定compact参数不降低HWM,cascade参数关联索引

收集统计信息

ANALYZE TABLE … [ESTIMATE|COMPUTE] STATISTICS;
EXEC DBMS_STATS.GATHER_TABLE_STATS(<'USER'>,<'TABLE_NAME'>);