ORACLE水位线

  在Oracle数据的存储中,可以把存储空间想象为一个水库,数据想象为水库中的水。水库中的水的位置有一条线叫做水位线,

在Oracle中,这条线被称为高水位线(High-warter mark, HWM)。在数据库表刚建立的时候,由于没有任何数据,所以这个时候

水位线是空的,也就是说HWM为最低值。当插入了数据以后,高水位线就会上涨,但是这里也有一个特性,就是如果你采用delete

语句删除数据的话,数据虽然被删除了,但是高水位线却没有降低,还是你刚才删除数据以前那么高的水位。也就是说,这条高水

位线在日常的增删操作中只会上涨,不会下跌

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

中有多少数据,Oracle就扫描这么大的数据块,而是Oracle会扫描高水位线以下的数据块。现在来想象一下,如果刚才是一张刚刚

建立的空表,你进行了一次Select操作,那么由于高水位线HWM在最低的0位置上,所以没有数据块需要被扫描,扫描时间会极短。

而如果这个时候你首先插入了一千万条数据,然后再用delete语句删除这一千万条数据。由于插入了一千万条数据,所以这个时候

的高水位线就在一千万条数据这里。后来删除这一千万条数据的时候,由于delete语句不影响高水位线,所以高水位线依然在一千

万条数据这里。这个时候再一次用select语句进行扫描,虽然这个时候表中没有数据,但是由于扫描是按照高水位线来的,所以需

要把一千万条数据的存储空间都要扫描一次,也就是说这次扫描所需要的时间和扫描一千万条数据所需要的时间是一样多的。所以

有时候有人总是经常说,怎么我的表中没有几条数据,但是还是这么慢呢,这个时候其实奥秘就是这里的高水位线了。

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

的块。如果在执行删除操作后不降低高水位线标记,则将导致查询语句的性能低下。下面的方法都可以降低高水位线标记。

1.厉行表重建号召 alter table table_name move;
(在线迁移表空间ALTER TABLE 。。。 MOVE TABLESPACE 。。。
ALTER TABLE 。。。 MOVE 后面不跟参数也行,
不跟参数表还是在本来的表空间,move后记住重建索引
万一尔后还要继续向这个表添置数据,未曾必需move,
只是释放出来的空间,只能这个表用,其他的表可能segment无法利用该空间
)

2.厉行alter table table_name shrink space; 当心,此号召为Oracle 10g新增功能,再厉行该号召之前定然批准行挪动 alter table table_name enable row movement;
3.复制要保留的数据到临时表t,drop原表,然后rename临时表t为原表
4.emp/imp
5.alter table table_name deallocate unused
6.尽量truncate 吧

 

利用MOVE压缩表的高水位线

如果表的高水位线比较高,或者表经历了大数据量的产生操作,经常会使用ALTER TABLE MOVE的方法来减少表占用的空间。

案例介绍:两张表几乎一样大,而且都是空表。但是通过MOVE之后,得到的结果却完全不同。

查看表占用的实际空间。
SELECT SEGMENT_NAME, BYTES/1024/1024/1024 G 
 FROM USER_SEGMENTS
 WHERE SEGMENT_NAME like 'table';
查看表占用的实际空间。

利用move减少表占用的空间并尝试减少水位线。

 ALTER TABLE table1 MOVE;
 ALTER TABLE table2 MOVE;

重新查看两个表的实际空间,会发现两个表的数据虽然都为0,但是占用的空间相差却比较多。

造成这个现象的原因是由于table1 表只包含的一个初始EXTENT,而这个EXTENT的大小是1G,而table2 则包含很多的64K大小的

EXTENT。

查看用户的建表语句:
 SELECT DBMS_METADATA.GET_DDL('TABLE', TABLE_NAME) 
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'SAS_RE_REQUEST_MESSAGE%';

会发现INITIAL 参数指定了初始的EXTENT,而table1 的这个EXTENT的大小是1G,而table2则包含很多的64K大小的EXTENT

也就是说MOVE操作会根据原表的INITIAL大小为新表建立第1个EXTENT。MOVE不会自动减少表的初始扩展的大小。
因此对于表T_BIG_TABLE这种情况,执行MOVE的时候应该指定新的存储参数:
SQL> ALTER TABLE T_BIG_TABLE MOVE STORAGE (INITIAL 1M);

oracle 如何查看表 高水位线:
select blocks, empty_blocks from dba_tables where table_name='xxx' and owner='xx';
blocks就是已经分配的空间即HWM,实际分配的空间,不是实际大小

猜你喜欢

转载自polyangel.iteye.com/blog/1330670