關於 Oracle 的高水平線
high water mark 故名思義為高水平線 , 一般是相對一個表而言的 , 當一個表有資料不斷的插入時 ,high water mark 值不斷增高 , 對那些全表掃描的 select 查詢是以 high water mark 為終點的 , 雖然表中可能只有一行記錄 . 它是表的空間曾經擴充到的值 .
之所以對hwm產生了興趣還是緣於下午的那個resize事件,呵呵
建立一張 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;
執行後的圖與上面一樣,沒有發生任何變化
再執行 truncate 操作,把該表的高水平線恢複到原有的初始化階段
TRUNCATE TABLE TEST;
後見圖:
結論:
資料被刪除後,高水平線( 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