oracle HWM

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;
相關文章
相關標籤/搜索