所有的Oracle表都有一個容納數據的上限(很像一個水庫歷史最高的水位),我們把這個上限稱為“High water mark"或HWM。這個HWM是一個標記(專門有一個數據塊來記錄高水標記等),用來說明已經有多少數據塊分配給這個表。HWM通常增長的幅度為一次5個數據塊。
高水線的作用,HWM對數據庫的操作有如下影響:
- 全表掃描通常要讀出直到HWM標記的所有的屬於該表數據塊,即使該表中沒有任何數據。
- 即使HWM以下有空閑的數據塊,鍵入在插入數據時使用了append關鍵字,則在插入時使用HWM以上的數據塊,些時HWM會自動增大。
因此,高水線是Oracle優化時一個重要的參數。
通常,我們在表空間中創建一張表時,Oracle就會初始分配一些blocks/extents給該表,之后,隨着表中數據量的增加,也會相應的給表自動分配blocks/extents。
上機練習:
初始創建一張表HWM_TEST, 通過查詢DBA_SEGMENTS的列BLOCKS和EXTENTS可以得到已分配該表的BLOCKS和EXTENTS:
SQL>conn username/password
Connected
SQL>select blocks,empty_blocks,num_wors,from dba_tables where table_name='HWM_TEST';
BLOCKS EMPTY_BLOCKS NUM_ROWS
------------- -------------------- ------------------
103 9 8000 -->表HWM_TEST占用了103個block,9個block未使用,有8000行記錄。
SQL>select blocks,extents,header_block from dba_segments where segment_name='HWM_TEST';
BLOCKS EXTENTS HEADER_BLOCK
---------- ---------- ------------
112 14 83 -->Oracle總共為表HWM_TEST分配了112個block,14個extent,段頭(Segment Header)所在塊是83號。
SQL>delete from hwm_test where rownum < 3001; -->刪除部分數據。
3000 rows deleted.
SQL>commit;
Commit complete. -->提交。
現在我們再查詢DBA_TABLES、DBA_SEGMENTS時,統計數據是沒有任何變動的,需要分析一下:
SQL>analyze table hwm_test compute statistics;
Table analyzed.
SQL>select blocks,empty_blocks,num_rows from dba_tables where table_name='HWM_TEST';
BLOCKS EMPTY_BLOCKS NUM_ROWS
---------- ------------ ----------
103 9 5000 -->經過analyze后,發現統計的記錄數發生了變化,可數據塊的數量並沒有變化。
SQL>select blocks,extents,header_block from dba_segments where segment_name ='HWM_TEST';
BLOCKS EXTENTS HEADER_BLOCK
---------- ---------- ------------
112 14 83
那如何確定表HWM_TEST究竟使用了多少個block呢?可以通過ROWID的來查詢:
SQL>select count(distinct dbms_rowid.rowid_block_number(rowid)) "Used Blocks" from HWM_TEST;
Used Blocks
-----------
63
那現在可以明白:Oracle分配了112個block給HWM_TEST表,其中有103個數據塊保存用戶數據,但實際上是有63個block是實際用戶數據占用的block數。
降低高水線有多種方法:EXP/IMP、TRUNCATE或者使用MOVE,在10G,Oracle提供了shrink功能。使用哪種方法因人而異且需要根據實際情況,一般情況我習慣使用MOVE和SHRINK。
1、使用alter table ... shrink space
SQL>alter table HWM_TEST enable row movement;
Table altered. -->這是必須的步驟, 即將收縮(shrink)的數據表,必須啟用row movement。
SQL>alter table HWM_TEST shrink space;
Table altered. -->這就是收縮空間語句的廬山真面目,當然還可以加其他參數,如加級聯(cascade),就會把相應的索引段也進行收縮。
SQL>analyze table HWM_TEST compute statistics;
Table analyzed. -->再次分析表HWM_TEST。
SQL>select blocks,empty_blocks,num_rows from dba_tables where table_name='HWM_TEST';
BLOCKS EMPTY_BLOCKS NUM_ROWS
---------- ------------ ----------
63 9 5000 -->現在BLOCKS值變為63了。
2、使用alert table ... move
SQL>select blocks,empty_blocks,num_rows from dba_tables where table_name='HWM_TEST';
BLOCKS EMPTY_BLOCKS NUM_ROWS
---------- ------------ ----------
70 2 3001
SQL>alter table hwm_test move;
Table altered.
SQL>analyze table hwm_test compute statistics;
Table analyzed.
SQL>select blocks,empty_blocks,num_rows from dba_tables where table_name='HWM_TEST';
BLOCKS EMPTY_BLOCKS NUM_ROWS
---------- ------------ ----------
43 5 3001
使用alter table ... shrink space/move均可收縮表的高水線
本文出自 “FROG_HONG” 博客,請務必保留此出處http://76287.blog.51cto.com/66287/1025579