Oracle表段中的高水位線HWM : 在Oracle數據的存儲中,可以把存儲空間幻想爲一個水庫,數據幻想爲水庫中的水。 水庫中的水的方位有一條線叫作水位線,在Oracle中,這條線被稱爲高水位線(High-warter mark, HWM)。 在數據庫表剛樹立的時分,因爲沒有任何數據,因此這個時分水位線是空的,也就是說HWM爲最低值 。當刺進了數據從此,高水位線就會上漲, http://www.fp1111.info/linked/20130305.do; 但是這裏也有一個特性,就是如果你選用delete句子刪 除數據的話,數據儘管被刪去了,但是高水位線卻沒有降低,還是你方纔刪去數據從前那麼高的水 位。也就是說,這條高水位線在日常的增刪操做中只會上漲,不會跌落。HWM通常添加的起伏爲一次 5個數據塊. Select句子會對錶中的數據進行一次掃描,但是終究掃描多少數據存儲塊呢,這個並非說數據庫 中有多少數據,Oracle就掃描這麼大的數據塊,而是Oracle會掃描高水位線如下的數據塊。 瞭解高水位的效果:瞭解全表掃描的開支(試驗:如果) @@@@@@ 批改ORACLE表的高水位線 ORACLE中,履行對錶的刪去操做不會降低該表的高水位線。而全表掃描將一直讀取一個段(extent) 中一切低於高水位線符號的塊。如果在履行刪去操做後不降低高水位線符號,則將導致查詢句子的 功用低下。rebuild, truncate, shrink,move 等操做會降低高水位。 A、履行表重建指令 alter table table_name move;(把樓移到另外一塊地) B、 履行alter table table_name shrink space; 此指令爲Oracle 10g新增功用,再履行該指令之 前有必要答應行移動 alter table table_name enable row movement; C、 重建表 仿製要保存的數據到暫時表t,drop原表,而後rename暫時表t爲原表 D、 用邏輯導入導出: Emp/Imp E、. Alter table table_name deallocate unused DEALLOCATE UNUSED爲開釋HWM上面的未運用空間,但是並不會開釋HWM下面的自由空間,也不會移動 HWM的方位. F、 引薦運用truncate. @@@@@ ORACLE用HWM來界定一個段中運用的塊和未運用的塊. 舉個好比來講,當我們創立一個表時,ORACLE就會爲這個目標分配一個段.在這個段中,即使我們未插 入任何記載,也至少有一個區被分配,榜首個區的榜首個塊就稱爲段頭(SEGMENT HEADE),段頭中就儲 存了一些信息,其間HWM的信息就存儲在此.此刻,因爲榜首個區的榜首塊用於存儲段頭的一些信息,雖 然沒有存儲任何實踐的記載,但也算是被運用,此刻HWM是坐落第2個塊.當我們不斷刺進數據到表後, 第1個塊現已放不下後邊新刺進的數據,此刻,ORACLE將高水位之上的塊用於存儲新增數據,一塊兒,HWM 自身也向上移.也就是說,當我們不斷刺進數據時,HWM會往不斷上移,這樣,在HWM之下的,就代表運用 過的塊,HWM之上的就代表已分配但從未運用過的塊. HWM在刺進數據時,當現有空間缺少而進行空間的擴大時會向上移,但刪去數據時不會往下移. ORACLE 不會開釋空間以供其餘目標運用,有一條簡略的理由:因爲空間是爲新刺進的行保存的,並 且要習慣現有行的添加。被佔用的最高空間稱爲最高運用符號 (HWM), @@@ ORACLE的全表掃描是讀取高水位符號(HWM)如下的一切塊. @@@ 啥樣的刺進是在高水位上面進行刺進的?(append操做(不檢查高水位線可否有數據,效率高, 不寫日誌,糟蹋空間)) 當用直接途徑刺進行時,即使HWM如下有閒暇的數據庫塊,鍵入在刺進數據時運用了append關鍵詞, 則在刺進時運用HWM以上的數據塊,此刻HWM會主動增大。 例如,通過直接加載刺進(用 APPEND 提示刺進)或通過 SQL*LOADER 直接途徑 數據塊直接置於 HWM 之上。它下面的空間就糟蹋掉了。 @@@@ 關聯測驗: SQL> create table tt (id number);此刻表沒有剖析,是原始的數據,即8個數據塊。 SQL> select segment_name,segment_type,blocks from dba_segments where segment_nam e='TT'; SEGMENT_NAME -------------------------------------------------------------------------------- SEGMENT_TYPE BLOCK ------------------ ---------- TT TABLE 8(段佔用了多少個塊) SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table _name='TT'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------- ------------ TT declare i number; begin for i in 1..10000 loop insert into tt values(i); end loop; commit; end; / SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT'; SEGMENT_NAME SEGMENT_TYPE BLOCKS --------------- --------------- ---------- TT TABLE 24 註釋:user_dbasegments中的BLOCKS 列表明該表中從前運用過得數據庫塊的數目 dba_dbasegments中的BLOCKS 列表明段佔用多少個塊 SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS --------------- ---------- ---------- ------------ TT 此刻表TT 佔用的數據庫現已經是24個了。 但是user_tables 顯現的信息還是爲空。 因爲沒有作計算 剖析。 exec DBMS_STATS.GATHER_TABLE_STATS('SYS','TT');(蒐集計算信息) SQL> exec DBMS_STATS.GATHER_TABLE_STATS('SYS','TT');(蒐集計算信息) PL/SQL 進程已成功完結。 SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS --------------- ---------- ---------- ------------ TT 10000 20 0 此刻user_tables 現已有了數據,顯現的運用了20個數據塊。 但是empty_blocks 還是爲空。 這裏要注重的當地。 這個字段只需運用analyze 蒐集計算信息以後纔會有數據。 5) 運用analyze 蒐集計算信息 SQL> ANALYZE TABLE TT COMPUTE STATISTICS; Table analyzed. SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS --------------- ---------- ---------- ------------ TT 10000 20 3 這個時分高水位在哪裏呢?20(20 3=23<24) 這裏有顯現空的數據庫有3個。 注重:20 3=23. 比佔用的24個數據塊少一個。因爲有一個數據庫塊被保存用做segment header。 delete 數據 看可否會影響他的段鉅細 delete from tt; commit SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT'; SEGMENT_NAME SEGMENT_TYPE BLOCKS --------------- --------------- ---------- TT TABLE 24 SQL>analyze table tt compute statistics;(算出高水位線在那一塊) SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table _name='TT';(blocks爲高水位線) TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------- ------------ TT 0 20 3 這裏我們可以證實了啥:高水位不受delete 影響 SQL>insert into tt select * from tt;(tt現已刪去沒有數據) SQL> insert into tt select rownum from dba_objects; 已創立50323行。 SQL>analyze table tt compute statistics; SQL> select table_name,num_rows,blocks,empty_blocks from user_tables where table _name='TT';(檢查高水位線(blocks))大於20 TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------- ------------ TT 50323 79 0 這裏我們可以證實了啥:高水位不受commit影響,只需有刺進數據HWM就會添加 @@@@@ 開釋高水位(truncate) SQL> truncate table tt; 表被切斷。 SQL> ANALYZE TABLE TT COMPUTE STATISTICS; 表已剖析。 SQL> select segment_name,segment_type,blocks from dba_segments where segment_nam e='TT'; SEGMENT_NAME -------------------------------------------------------------------------------- SEGMENT_TYPE BLOCKS ------------------ ---------- TT TABLE 8(又回到原本的8) http://www.fpshamen.com/linked/20130305.do;