ORACLE---高水位,以及高水位的破解法
1.什麼是高水位?(high water mark 簡稱:HWM)
所有的oracle段(segments,在此,為了理解方便,建議把segment作為表的一個同義詞)都有一個在段記憶體放資料的上線,那麼我們把這個上線成為“high water mark”或HWM.HWM是一個標記,用來說明已經有多少沒有使用的資料塊分配給了這個segment。MWM通常增長的幅度為一次5個數據塊。原則上
MWM只會增大,不會縮小。即使表中的全部資料都刪除了,那麼HWM還是原值,不會變,由於這個特點,使得HWM就像一個水庫的歷史最高水位。
簡單的說就像水庫裡的歷史最高水位。 就如剛挖的水庫一樣裡面沒有一滴水,那麼它的最高水位為0.同理在剛建的新表中
由於沒有一條資料,所以的高水位是0,隨著不斷的往裡面新增資料,進行增刪操作,那麼它的高水位就會上漲。 當然也不是
說你把表的資料刪掉一半,它的高水位就會下降,因為高水位代表歷史最高水位。 在Oracle中執行delete刪除操作不會降低高水位。執行truncate
操作可以降低高水位,通常能把高水位降到0. 所以為了降低高水位,能儘量使用truncate的就不使用delete操作。
---------也就是說進行增刪操作只會上漲,不會下跌!!!
2.select 特性和高水位的關係
在Oracle中執行select 操作掃描的是高水位以下的全部資料塊。所以不是說資料庫中存放了多少資料塊,就會掃描多少個數據塊。現在回想以下,如果是一個新建的表,裡面沒有資料,那麼你執行select 掃描操作,那麼高水位線基本就在0上,所以就沒有資料塊被掃描。掃描的時間就會用的很少。但是現在你往表裡
插入1000萬條資料,然後再執行delete操作,但是由於delete操作不影響高水位線,所以高水位線還是原來的高水位線。
----------所以就有人經常會說我的表中明明沒有一條資料,但是執行select掃描怎麼會那麼慢呢,這個時候裡面的奧祕就在於高水位線了!
3.為什麼要降低高水位?
就行水庫洩洪一樣,你會開啟水閘把超出最高水位預警線的水消退掉。 那麼在Oracle中高水位以下存放的都是資料塊,每次全表掃描的時候
都會把高水位以下的全部資料庫都掃描一邊,如此以來就會很浪會資源,響應時間比較長。 反之,如果我們把高水位降低,那麼每次全表掃描的時候
是不是掃描的資料塊是不是就少了。
4.為什麼出來一個低HWM?
在管理段的時候通常有兩種方法:手動管理段空間(Manual Segment Space Management )和自動段空間(Automatic Segment Space Management)。
在手動管理段空間的時候,段中只有一個HWM,但是為什麼又會有一個低HWM呢?其實這都是因為自動管理段空間造成的。 在手動管理的時候
資料插入到新的資料塊中,資料庫塊就先會被格式化然後等待資料訪問,但是在自動管理中呢,資料插入到新的資料塊中,資料塊並沒有被格式化,而是在第一次訪問這個資料庫塊的時候才格式化這個塊。所以我們又需要一條水位線,用來標示已經被格式化的快。這條線就叫做低HWM.
一般來說,低HWM肯定地獄HWM.
5.HWM資料庫的操作有如下影響:
a)全表掃描通常要讀出直到hwm標記的所有的屬於該表資料塊,及時該表中沒有任何資料。
b)即使HWM以下有空閒的資料塊,鍵入在插入資料是使用了APPEND關鍵字,則在插入時用用HWM以上的資料塊,此時HWM會自動增大。
6.那麼如何降低高水位呢?
降低高水位通常有很多辦法。就比如抗洪,你是如何想把洪水消退,可能會想到把水庫的水閘開啟,把水放掉。。。。。。
但是在Oracle中降低高水位通常有以下辦法:
1.能使用truncate的儘量不適用delete操作。
2.新建一個臨時表,把資料複製到臨時表,然後把源表drop掉,再把臨時表重新命名為源表的名字。
3.移動表空間。(或者不移動表空間)
4.執行表重建命令(alter table table_name move;)(線上轉移表空間ALTER TABLE 。。。 MOVE TABLESPACE 。。。ALTER TABLE 。。。 MOVE 後面不跟引數也行,不跟引數表還是在原來的表空間,move後記住重建索引。如果以後還要繼續向這個表增加資料,沒有必要move,只是釋放出來的空間,只能這個表用,其他的表或者segment無法使用該空間)
5.執行alter table table_name shrink space; 注意,此命令為Oracle 10g新增功能,再執行該指令之前必須允許行移動alter table table_name enable row movement;
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------以下是測試案例:
(1).新建t1表,插入34816條資料。提交。 並且執行以下步驟:
SQL> analyze table t1 compute statistics;------分析表
Table analyzed.
SQL> select num_rows ,blocks,empty_blocks from user_tables where table_name='T1'; ---第一次檢視高水位線
NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
34816 212 43
-------------------
SQL> alter table t1 move;------執行表重建命令
Table altered.
SQL> analyze table t1 compute statistics;---再次分析表
Table analyzed.
SQL> select num_rows ,blocks,empty_blocks from user_tables where table_name='T1';-----再次檢視高水位線
NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
34816 208 47
/block 從212降到208,說明高水位線降低了。------------可行。
------------------------------------------------------------------------------------------------------------------------
(2)新建t1表,插入34816條資料。提交。 並且執行以下步驟:
SQL> truncate table t1 ;
Table truncated.
SQL> select num_rows ,blocks,empty_blocks from user_tables where table_name='T1';
NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
34816 208 47
SQL> analyze table t1 compute statistics;
Table analyzed.
SQL> select num_rows ,blocks,empty_blocks from user_tables where table_name='T1';
NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
0 0 7
// 說明truncate 有效。
----------------------------------------------------------------------------------------------
(3)新建t1表,插入34816條資料。提交。 並且執行以下步驟:
複製要保留的資料到臨時表t,drop原表,然後rename臨時表t為原表 -----------改方法可行,已經驗證。
--------------------------------------------------------------------------
(4)新建t1表,插入34816條資料。提交。 並且執行以下步驟:
Alter table table_name deallocate unused(驗證不可行,不降低水位線)
注:這證明,DEALLOCATE UNUSED為釋放HWM上面的未使用空間,但是並不會釋放HWM下面的自由空間,也不會移動HWM的位置.