說到HWM,我們首先要簡要的談?wù)凮RACLE的邏輯存儲管理。我們知道负溪,ORACLE在邏輯存儲上分4個粒度: 表空間济炎,段,區(qū)和塊崖堤。
- 塊(Oracle數(shù)據(jù)塊)
塊是Oracle粒度最小的存儲單位耐床,不同于操作系統(tǒng)磁盤塊,現(xiàn)在標(biāo)準(zhǔn)的Oracle塊大小是8K胯甩,ORACLE每一次I/O操作也是按塊來操作的堪嫂,也就是說當(dāng)ORACLE從數(shù)據(jù)文件讀數(shù)據(jù)時,是讀取多少個塊淹办,而不是多少行恶复。
- 區(qū)
由一系列相鄰的塊而組成,這也是ORACLE空間分配的基本單位塔插,舉個例子來說拓哟,當(dāng)我們創(chuàng)建一個表PM_USER時伶授,首先ORACLE會分配一區(qū)的空間給這個表,隨著不斷的INSERT數(shù)據(jù)到PM_USER违诗,原來的這個區(qū)容不下插入的數(shù)據(jù)時疮蹦,ORACLE是以區(qū)為單位進行擴展的拜隧,也就是說再分配多少個區(qū)給PM_USER壁公,而不是多少個塊紊册。 一張表由若干區(qū)組成快耿,這些區(qū)可以是不相鄰的。
- 段
是由一系列的區(qū)所組成掀亥,一般來說,當(dāng)創(chuàng)建一個對象時(表遏片,索引)鳍侣,就會分配一個段給這個對象。所以從某種意義上來說线衫,段就是某種特定的數(shù)據(jù)惑折。如CREATE TABLE PM_USER
,這個段就是數(shù)據(jù)段白热,而CREATE INDEX ON PM_USER(NAME)
粗卜,ORACLE同樣會分配一個段給這個索引,但這是一個索引段了攻臀。查詢段的信息可以通過數(shù)據(jù)字典: SELECT * FROM USER_SEGMENTS
來獲得刨啸, 通俗的講识脆,一張表對應(yīng)一個段善已。
- 表空間
包含段换团,區(qū)及塊粘招。表空間的數(shù)據(jù)物理上儲存在其所在的數(shù)據(jù)文件中,一個數(shù)據(jù)庫至少要有一個表空間(SYSTEM)辑甜。一個表空間可能會保存在多個數(shù)據(jù)文件中袍冷。
HWM
在Oracle數(shù)據(jù)的存儲中,可以把存儲空間想象為一個水庫邓线,數(shù)據(jù)想象為水庫中的水煌恢。水庫中的水的位置有一條線叫做水位線,在Oracle中你雌,這條線被稱為高水位線(High-warter mark二汛, HWM)。
ORACLE用HWM來界定一個段中使用過的塊和未使用的塊氓栈。
在數(shù)據(jù)庫表剛建立的時候婿着,由于沒有任何數(shù)據(jù),所以這個時候水位線是空的提完,也就是說HWM為最低值。當(dāng)插入了數(shù)據(jù)以后挡篓,HWM就會上漲帚称,但是這里也有一個特性闯睹,就是采用delete
語句刪除數(shù)據(jù)的話担神,數(shù)據(jù)雖然被刪除了,但是HWM卻沒有降低孩锡,還是刪除數(shù)據(jù)以前那么高的水位亥贸。
如果該表所在的表空間還有空閑,則新insert
的記錄不會覆蓋之前delete
的記錄荣挨,而是會在新的位置插入朴摊,從而提升HWM。也就是說口锭,HWM在日常的增刪操作中只會上漲贩疙,不會下跌。
Oracle中Select
語句會對表中的數(shù)據(jù)進行一次掃描这溅,但是究竟掃描多少數(shù)據(jù)存儲塊呢悲靴,這個并不是說數(shù)據(jù)庫中有多少數(shù)據(jù),Oracle就掃描這么大的數(shù)據(jù)塊耸三,而是Oracle會掃描高水位線以下的數(shù)據(jù)塊。
這樣仪壮,頻繁insert
和delete
的臨時表胳徽,由于水線的提升爽彤,查詢逐漸變慢就不奇怪了适篙。
重置HWM
在ORACLE中箫爷,執(zhí)行對表的delete
操作不會降低該表的高水位線。而全表掃描將始終讀取一個段中所有低于HWM的塊硫痰。如果在執(zhí)行刪除操作后不降低高水位線標(biāo)記翁都,則將導(dǎo)致查詢語句的性能低下。
那有沒有辦法讓高水位線下降呢柄慰,比較簡單的方法是采用TRUNCATE
語句進行刪除數(shù)據(jù)坐搔。采用TRUNCATE
語句刪除一個表的數(shù)據(jù)的時候,類似于重新建立了表蠢挡,不僅把數(shù)據(jù)都刪除了凳忙,還把HWM給清空恢復(fù)為0。所以如果需要把表清空涧卵,在有可能利用TRUNCATE
語句來刪除數(shù)據(jù)的時候就利用TRUNCATE
語句來刪除表柳恐,特別是那種數(shù)據(jù)量有可能很大的臨時存儲表。
下面的方法都可以降低高水位線標(biāo)記讼庇。
幾種重置HWM的方法
- MOVE表
MOVE表要求表空間剩余2倍當(dāng)前表大小近尚,且MOVE后需要重建索引。
- SHRINK表
注意歼跟,此命令為Oracle 10g新增功能,執(zhí)行該指令之前必須允許行移動alter table table_name enable row movement;
復(fù)制要保留的數(shù)據(jù)到臨時表t嘹承,drop原表叹卷,然后rename臨時表t為原表
alter table table_name deallocate unused
truncate
表