oracle9.2如何在不使用truncate语句的情况下将HWM高水位线拉回来

来源:百度知道 编辑:UC知道 时间:2024/05/25 05:38:27
在Oracle数据的存储中,可以把存储空间想象为一个水库,数据想象为水库中的水。水库中的水的位置有一条线叫做水位线,在Oracle中,这条线被称为高水位线(High-warter mark, HWM)。在数据库表刚建立的时候,由于没有任何数据,所以这个时候水位线是空的,也就是说HWM为最低值。当插入了数据以后,高水位线就会上涨,但是这里也有一个特性,就是如果你采用delete语句删除数据的话,数据虽然被删除了,但是高水位线却没有降低,还是你刚才删除数据以前那么高的水位。也就是说,这条高水位线在日常的增删操作中只会上涨,不会下跌。
下面我们来谈一下Oracle中Select语句的特性。Select语句会对表中的数据进行一次扫描,但是究竟扫描多少数据存储块呢,这个并不是说数据库中有多少数据,Oracle就扫描这么大的数据块,而是Oracle会扫描高水位线以下的数据块。现在来想象一下,如果刚才是一张刚刚建立的空表,你进行了一次Select操作,那么由于高水位线HWM在最低的0位置上,所以没有数据块需要被扫描,扫描时间会极短。而如果这个时候你首先插入了一千万条数据,然后再用delete语句删除这一千万条数据。由于插入了一千万条数据,所以这个时候的高水位线就在一千万条数据这里。后来删除这一千万条数据的时候,由于delete语句不影响高水位线,所以高水位线依然在一千万条数据这里。这个时候再一次用select语句进行扫描,虽然这个时候表中没有数据,但是由于扫描是按照高水位线来的,所以需要把一千万条数据的存储空间都要扫描一次,也就是说这次扫描所需要的时间和扫描一千万条数据所需要的时间是一样多的。所以有时候有人总是经常说,怎么我的表中没有几条数据,但是还是这么慢呢,这个时候其实奥秘就是这里的高水位线了。
那有没有办法让高水位线下降呢,其实有一种比较简单的方法,那就是采用TRUNCATE语句进行删除数据。采用TRUNCATE语句删除一个表的数据的时候,类似于重新建立了表,不仅把数据都删除了,还把HWM给清空恢复为0。所以如果需要把表清空,在有可能利用TRUNCATE语句来删除数据的时候就利用TRUNCATE语句来删除表,特别是那种数据量有可能很大的临时存储表。
但是目前我需要保存大概一个星期的数据所以不能使用truncate,是否有其它方法

建一个临时表,truncate前,先备份到临时表里
然后,truncate,执行完毕后,把临时表的数据insert into到正式表中
然后再把临时表truncate掉

这样就满足你的要求了,不过麻烦
不过1000W的数据,你就是insert into也得很长时间了........

1楼的说的有道理,
你写个储存过程:
create or replace 储存名称
is
cnt number;
begin
select count(*) into v_cnt from user_all_tables
where table_name='建立的临时表';
IF v_cnt > 0 then
execute immediate 'drop table 建立的临时表';
end if;
create table 建立的临时表 as select * from 正式表 where 条件;
..........
接着进行你的操作
..........
execute immediate 'truncate table 建立的临时表';
end;

SQL> ALTER TABLE <table_name> ENABLE ROW MOVEMENT;
SQL> ALTER TABLE <table_name> SHRINK SPACE [COMPACT] [CASCADE];

试试上面的命令吧

使用 table partition。你可以 drop old partition。

1楼的方法,理论上行,但一千万的数据,实际操作起来会有很大麻烦。你得用很大的空间来储存 archive log。I/O, CPU 将会被 hit hard.

3楼的方法,delete后的空间,是无法用"SHRINK SPACE"重新获得。