关于 Oracle 的高水平线
 
high water mark 故名思义为高水平线 , 一般是相对一个表而言的 , 当一个表有数据不断的插入时 ,high water mark 值不断增高 , 对那些全表扫描的 select 查询是以 high water mark 为终点的 , 虽然表中可能只有一行记录 . 它是表的空间曾经扩充到的值 .
之所以对hwm产生了兴趣还是缘于下午的那个resize事件,呵呵ITPUB个人空间

 
创建一张 test 表
-- Create table
create table TEST
(
 A CHAR(1024)
);
 
select * from dba_extents where segment_name='TEST'
后见图:表创建的时候会按照初始化参数进行创建,默认是 Initial extent 为 64k ,包含 8 个数据块。
 

 
插入 1000 条原始记录, 1000*1k 约等于 1M
declare
 -- Local variables here
 i integer;
begin
 -- Test statements here
 for i in 1..1000
 loop
   INSERT INTO TEST VALUES(I);
 end loop;
 COMMIT;
end;
 
select SUM(BYTES) from user_extents where segment_name='TEST' 
select * from dba_extents where segment_name='TEST'
后见图:
执行 delete 操作
Delete * from test;
执行后的图与上面一样,没有发生任何变化
关于Oracle的高水平线_第1张图片
 
再执行 truncate 操作,把该表的高水平线恢复到原有的初始化阶段
TRUNCATE TABLE TEST;
后见图:
关于Oracle的高水平线_第2张图片
 
结论:
数据被删除后,高水平线( high-water mark , HWM )并没有复位只是那些空间不再使用而已,再次查询依然会读取 HWH 以前的块查找是否有可用的数据。而截断表将复位 HWH ,告诉这些空间没有保存数据。
 
其他引申出来的问题:
在插入测试 的数据过程中,如果首先插入 100 条、 200 条的时候,数据库 分配区间是以 64k 为单位分配的,当插入到 1000 条时,新分配的区间突然变为 1M 。
我反复查看了该表的 storage 定义
storage
 (
   initial 64K
   minextents 1
   maxextents unlimited
 );
只是没有 next extent 的定义而已,又找了很久 9i 、 10g 的官方文档,发现对 next extent 的解释还是按照早期版本的说法,定义多少分配多少,百思不得其解。
 
还是通过 google 找到的介绍:
先分配 16 个 64K 的 extent ,
0-15 extents 每个大小是 64K 合计大小 1M
16 - 79 extents 每个大小是 1M 合计大小 63M -- 以上两项大小合计 64M
80 - 199 extents 每个大小是 8M 合计大小 960M -- 以上三项大小合计 1024M = 1G
200 -?? extents 每个大小是 64M
 
具体参考文档,详见:
Oracle10g extent autoallocate 分配时,表是如何分配空间
http://space.itpub.net/35489/viewspace-84692
 
Oracle9i tablespace 空间分配中 initial_extent 与 LMT,DMT
http://space.itpub.net/35489/viewspace-503836