HWM指数据存储空间中,标识数据存储上限的一个标记。可以看作数组索引位置,唯一不同的是,当数据删除时,此索引位置不会自动减小,而是一直处于最高点。除非
手动方法进行恢复。查询操作中,Oracle只会对处于高水位之下的数据进行扫描。对于新建的表,高水位线可以看作在数组索引的0位置,此时扫描速度很快。如果插入了大量数量,再进行delete操作,此时,数据虽然删除了,但是高水位线却没有再减小到索引0位置。因此,Oracle依旧会进行一个全部高水位线下的扫描,因此扫描速度可能也会很慢。 自动段空间管理中,增加了一个低水位线的概念,自动段空间管理中,数据插入后,数据块并没有格式化,而是等第一次访问时才被格式化。低水位线就是表示已经被格式化的块。通常情况下,低水位线小于等于高水位线。
一、修改高水位线
1.1 表迁移,释放的是高水位之下的空间。
可以使用alter table table_name move tablespace tablespace_name;--可以不跟表空间参数。
MOVE后索引失效,需要重建索引。
如果要同时压缩表的索引,可以发布:alter table test_tab shrink space cascade
1.2使用10g后新增功能,收缩表空间
先记用行迁移,再收缩空间
alter table table_name enable row movement;
alter table table_name shrink space;
1.3 建立临时数据表,把数据复制过来,删除原来的表,再重新命名临时表为原表名字
1.4导出导入操作
1.5 alter table table_name deallocate unused.--释放的是高水位之上已经分配但没使用的区块。
1.6 truncate table table_name,截断表,索引到0位置。
HWM特点:
1.用来界定段中未使用的块和已经使用的块。
当创建表时,ORACLE会为此表对象分配一个段,在这个段中,即便未插入记录,也至少存在一个被分配的区,这个区的第一个块称segment header,里面记录关于存储的一些信息,HWM信息也会记录其中。此时,HWM在第二个块中,以后随着数据的插入,HWM不断上移(或后移),
HWM之下(或之前)的块称为已经使用过的块,之后的块则为未使用的块。
2.ORACLE插入数据时,如果现在空间不足或使用了APPEND的HINT方法,则在HWM之上分配数据块,但是删除数据时,HWM不会下称。
3.HWM的信息存储在SEGMENT HEADER
手工管理的段空间时,通过FREELIST管理段内空间。在ASSM(自动段空间管理),通过BITMAP管理段内空间分配。
4.查询时,只扫描HWM以下的块。
测试:
1、创建测试表
SQL> create table testhwm(name varchar2(32));
Table created
2.查看段中分配的块
SQL> select segment_name,segment_type,blocks from dba_segments where segment_name='TESTHWM';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
-------------------------------------------------------------------------------- ------------------ ----------
TESTHWM TABLE 8
3.查看区中相关信息
SQL> select SEGMENT_NAME,SEGMENT_TYPE,BLOCK_ID,BLOCKS,BYTES from dba_extents where segment_name='TESTHWM';
SEGMENT_NAME SEGMENT_TYPE BLOCK_ID BLOCKS BYTES
-------------------------------------------------------------------------------- ------------------ ---------- ---------- ----------
TESTHWM TABLE 89760 8 65536
4.从用户表查看相关信息
SQL> select table_name,num_rows,empty_blocks from user_tables t where t.table_name='TESTHWM';
TABLE_NAME NUM_ROWS EMPTY_BLOCKS
------------------------------ ---------- ------------
TESTHWM
5.插入测试数据。
SQL> begin
2 for i in 1..20000 loop
3 insert into testhwm values ('NAME'||i);
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed
SQL> commit;
Commit complete
SQL> select segment_name,segment_type,blocks from dba_segments where segment_name='TESTHWM';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
-------------------------------------------------------------------------------- ------------------ ----------
TESTHWM
TABLE 48
SQL> select SEGMENT_NAME,SEGMENT_TYPE,BLOCK_ID,BLOCKS,BYTES from dba_extents where segment_name='TESTHWM';
SEGMENT_NAME SEGMENT_TYPE BLOCK_ID BLOCKS BYTES
-------------------------------------------------------------------------------- ------------------ ---------- ---------- ----------
TESTHWM TABLE 89760 8 65536
TESTHWM TABLE 89768 8 65536
TESTHWM TABLE 89776 8 65536
TESTHWM TABLE 89784 8 65536
TESTHWM TABLE 89792 8 65536
TESTHWM TABLE 89800 8 65536
SQL> select table_name,num_rows,empty_blocks from user_tables t where t.table_name='TESTHWM';
TABLE_NAME NUM_ROWS EMPTY_BLOCKS
------------------------------ ---------- ------------
TESTHWM
此时插入数据占用的块达到48个,但是由于没有对表TESTHWM做分析,因此相关信息没有反应到USER_TABLES;
6.对表TESTHWM进行分析统计
SQL> exec dbms_stats.gather_table_stats('SYS','TESTHWM');
PL/SQL procedure successfully completed
7.查询现在USER_TABLE表中相关TESTHWM的信息
SQL> select table_name,num_rows,blocks,empty_blocks from user_tables t where t.table_name='TESTHWM';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ---------- ------------
TESTHWM 20000 44 0
EMPTY_BLOCKS为空,理论上应该显示有48 - 44 = 4 个块。EMPTY_BLOCKS的值只有进行analyze后收集信息后才有效。
8.分析表
SQL> analyze table testhwm compute statistics;
Table analyzed
SQL> select table_name,num_rows,blocks,empty_blocks from user_tables t where t.table_name='TESTHWM'
2 ;
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ---------- ------------
TESTHWM 20000 44 3
SQL> select segment_name,segment_type,blocks from dba_segments where segment_name='TESTHWM';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
-------------------------------------------------------------------------------- ------------------ ----------
TESTHWM TABLE 48
目前显示的总块数为44+3 = 47块,比分配的少一块,正好验证了上文,第一个块用作SEGMENT HEADER,存储一些基本信息,比如HWM基本信息,数据存储相关信息,锁信息等。
9.用DELETE删除数据。
SQL> delete from testhwm;
20000 rows deleted
SQL> commit;
Commit complete
SQL> select segment_name,segment_type,blocks from dba_segments where segment_name='TESTHWM';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
-------------------------------------------------------------------------------- ------------------ ----------
TESTHWM TABLE 48
SQL> select table_name,num_rows,blocks,empty_blocks from user_tables t where t.table_name='TESTHWM';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ---------- ------------
TESTHWM 20000 44 3
SQL> analyze table testhwm compute statistics;
Table analyzed
SQL> select segment_name,segment_type,blocks from dba_segments where segment_name='TESTHWM';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
-------------------------------------------------------------------------------- ------------------ ----------
TESTHWM TABLE 48
SQL> select table_name,num_rows,blocks,empty_blocks from user_tables t where t.table_name='TESTHWM';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ---------- ------------
TESTHWM 0 44 3
可以发现占用的块空间并未减少。
10、用TRUNCATE 截断表
SQL> truncate table testhwm;
Table truncated
SQL> select segment_name,segment_type,blocks from dba_segments where segment_name='TESTHWM';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
-------------------------------------------------------------------------------- ------------------ ----------
TESTHWM TABLE 8
SQL> select table_name,num_rows,blocks,empty_blocks from user_tables t where t.table_name='TESTHWM';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ---------- ------------
TESTHWM 0 44 3
SQL> analyze table testhwm compute statistics;
Table analyzed
SQL> select segment_name,segment_type,blocks from dba_segments where segment_name='TESTHWM';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
-------------------------------------------------------------------------------- ------------------ ----------
TESTHWM TABLE 8
SQL> select table_name,num_rows,blocks,empty_blocks from user_tables t where t.table_name='TESTHWM';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ---------- ------------
TESTHWM 0 0 7
使用TUNCATE后,HWM降低。
阅读(1808) | 评论(0) | 转发(0) |