1、什麼是水線(High Water Mark)?
全部的oracle段(segments,在此,爲了理解方便,建議把segment做爲表的一個同義詞) 都有一個在段內容納數據的上限,咱們把這個上限稱爲"high water mark"或HWM。這個HWM是一個標記,用來講明已經有多少沒有使用的數據塊分配給這個segment。HWM一般增加的幅度爲一次5個數據塊,原則上HWM只會增大,不會縮小,即便將表中的數據所有刪除,HWM仍是爲原值,因爲這個特色,使HWM很象一個水庫的歷史最高水位,這也就是HWM的原始含義,固然不能說一個水庫沒水了,就說該水庫的歷史最高水位爲0。可是若是咱們在表上使用了truncate命令,則該表的HWM會被從新置爲0。數據庫
2、HWM數據庫的操做有以下影響:
a) 全表掃描一般要讀出直到HWM標記的全部的屬於該表數據庫塊,即便該表中沒有任何數據。
b) 即便HWM如下有空閒的數據庫塊,鍵入在插入數據時使用了append關鍵字,則在插入時使用HWM以上的數據塊,此時HWM會自動增大。oracle
4、Oracle表段中的高水位線HWM
在Oracle數據的存儲中,能夠把存儲空間想象爲一個水庫,數據想象爲水庫中的水。水庫中的水的位置有一條線叫作水位線,在Oracle中,這條線被稱爲高水位線(High-warter mark, HWM)。在數據庫表剛創建的時候,因爲沒有任何數據,因此這個時候水位線是空的,也就是說HWM爲最低值。當插入了數據之後,高水位線就會上漲,可是這裏也有一個特性,就是若是你採用delete語句刪除數據的話,數據雖然被刪除了,可是高水位線卻沒有下降,仍是你剛纔刪除數據之前那麼高的水位。也就是說,這條高水位線在平常的增刪操做中只會上漲,不會下跌。 app
下面咱們來談一下Oracle中Select語句的特性。Select語句會對錶中的數據進行一次掃描,可是究竟掃描多少數據存儲塊呢,這個並非說數據庫中有多少數據,Oracle就掃描這麼大的數據塊,而是Oracle會掃描高水位線如下的數據塊。如今來想象一下,若是剛纔是一張剛剛創建的空表,你進行了一次Select操做,那麼因爲高水位線HWM在最低的0位置上,因此沒有數據塊須要被掃描,掃描時間會極短。而若是這個時候你首先插入了一千萬條數據,而後再用delete語句刪除這一千萬條數據。因爲插入了一千萬條數據,因此這個時候的高水位線就在一千萬條數據這裏。後來刪除這一千萬條數據的時候,因爲delete語句不影響高水位線,因此高水位線依然在一千萬條數據這裏。這個時候再一次用select語句進行掃描,雖然這個時候表中沒有數據,可是因爲掃描是按照高水位線來的,因此須要把一千萬條數據的存儲空間都要掃描一次,也就是說此次掃描所須要的時間和掃描一千萬條數據所須要的時間是同樣多的。因此有時候有人老是常常說,怎麼個人表中沒有幾條數據,可是仍是這麼慢呢,這個時候其實奧祕就是這裏的高水位線了。性能
那有沒有辦法讓高水位線降低呢,其實有一種比較簡單的方法,那就是採用TRUNCATE語句進行刪除數據。採用TRUNCATE語句刪除一個表的數據的時候,相似於從新創建了表,不只把數據都刪除了,還把HWM給清空恢復爲0。因此若是須要把表清空,在有可能利用TRUNCATE語句來刪除數據的時候就利用TRUNCATE語句來刪除表,特別是那種數據量有可能很大的臨時存儲表。spa
在手動段空間管理(Manual Segment Space Management)中,段中只有一個HWM,可是在Oracle9iRelease1才添加的自動段空間管理(Automatic Segment Space Management)中,又有了一個低HWM的概念出來。爲何有了HWM還又有一個低HWM呢,這個是由於自動段空間管理的特性形成的。在手段段空間管理中,當數據插入之後,若是是插入到新的數據塊中,數據塊就會被自動格式化等待數據訪問。而在自動段空間管理中,數據插入到新的數據塊之後,數據塊並無被格式化,而是在第一次在第一次訪問這個數據塊的時候才格式化這個塊。因此咱們又須要一條水位線,用來標示已經被格式化的塊。這條水位線就叫作低HWM。通常來講,低HWM確定是低於等於HWM的。索引
5、修正ORACLE表的高水位線
在ORACLE中,執行對錶的刪除操做不會下降該表的高水位線。而全表掃描將始終讀取一個段(extent)中全部低於高水位線標記的塊。若是在執行刪除操做後不下降高水位線標記,則將致使查詢語句的性能低下。下面的方法均可以下降高水位線標記。
1.執行表重建指令 alter table table_name move;
(在線轉移表空間ALTER TABLE 。。。 MOVE TABLESPACE 。。。ALTER TABLE 。。。 MOVE 後面不跟參數也行,不跟參數表仍是在原來的表空間,move後記住重建索引。若是之後還要繼續向這個表增長數據,沒有必要move,只是釋放出來的空間,只能這個表用,其餘的表或者segment沒法使用該空間)
2.執行alter table table_name shrink space; 注意,此命令爲Oracle 10g新增功能,再執行該指令以前必須容許行移動alter table table_name enable row movement;
3.複製要保留的數據到臨時表t,drop原表,而後rename臨時表t爲原表
4.emp/imp
5.alter table table_name deallocate unused
6.儘可能truncate吧table