1. 程式人生 > >ORACLE---高水位,以及高水位的破解法

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的位置.