熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

oracle的高水位線(HWM)

2013-11-13 15:48:08  來源: Oracle 

  由之前的面試題一中學到的知識

  現在解釋下什麼是高水位

  oracle的邏輯存儲結構表空間——>段——>區——>塊

  塊:是粒度最小的存儲單位現在標准的塊大小是KORACLE每一次I/O操作也是按塊來操作的也就是說當ORACLE從數據文件讀數據時是讀取多少個塊而不是多少行

  區:由一系列相鄰的塊而組成這也是ORACLE空間分配的基本單位舉個例子來說當我們創建一個表A時首先ORACLE會分配一區的空間給這個表隨著不斷的INSERT數據到A原來的這個區容不下插入的數據時ORACLE是以區為單位進行擴展的也就是說再分配多少個區給A而不是多少個塊

  段:是由一系列的區所組成一般來說當創建一個對象時(表索引)就會分配一個段給這個對象所以從某種意義上來說段就是某種特定的數據如CREATE TABLE PM_USER這個段就是數據段而CREATE INDEX ON PM_USER(NAME)ORACLE同樣會分配一個段給這個索引但這是一個索引段了查詢段的信息可以通過數據字典: SELECT * FROM USER_SEGMENTS來獲得

  表空間:包含段區及塊表空間的數據物理上儲存在其所在的數據文件中一個數據庫至少要有一個表空間

  所有的oracle段都有一個在段內容納數據的上限我們把這個上限稱為high water mark或HWM這個HWM是一個標記用來說明已經有多少沒有使用的數據塊分配給這個segment

  HWM通常增長的幅度為一次個數據塊原則上HWM只會增大不會縮小即使將表中的數據全部刪除HWM還是為原值由於這個特點使HWM很象一個水庫的歷史最高水位這也就是HWM的原始含義當然不能說一個水庫沒水了就說該水庫的歷史最高水位為但是如果我們在表上使用了truncate命令則該表的HWM會被重新置為

  如何知道一個表的HWM?

  a) 首先對表進行分析:

  ANALYZE TABLE <tablename> ESTIMATE/COMPUTE STATISTICS;

  b) 查看相關信息

  SELECT blocks empty_blocks num_rows FROM user_tables WHERE table_name =<tablename>;

  [SYS@orcl] SQL>select segment_namesegment_typeblocks from dba_segments where segment_name=A;

  SEGMENT_NAME SEGMENT_TYPE BLOCKS

  

  A                  TABLE     

  可得到A表分配了個blocks

  [TEST@orcl] SQL>analyze table a compute statistics;

  表已分析

  [TEST@orcl] SQL>select num_rowsblocksempty_blocks from user_tables where table_name=A;

  NUM_ROWS     BLOCKS EMPTY_BLOCKS

  

                       

  BLOCKS 列代表該表中曾經使用過得數據庫塊的數目即水線EMPTY_BLOCKS 代表分配給該表但是在水線以上的數據庫塊即從來沒有使用的數據塊

  [TEST@orcl] SQL>delete from a;

  [TEST@orcl] SQL>analyze table a compute statistics;

  表已分析

  [TEST@orcl] SQL>select num_rowsblocksempty_blocks from user_tables where table_name=A;

  NUM_ROWS     BLOCKS EMPTY_BLOCKS

  

                       

  [TEST@orcl] SQL>select count(distinct dbms_rowidrowid_block_number(rowid)||

   dbms_rowidrowid_relative_fno(rowid)) used from a;

  used

  

      注Used = 這表名沒有任何數據庫塊容納數據即表中無數據

  [TEST@orcl] SQL>truncate table a;

  表被截斷

  [TEST@orcl] SQL>analyze table a compute statistics;

  表已分析

  [TEST@orcl] SQL>select table_nameblocksempty_blocks from user_tables where table_name=A;

  TABLE_NAME     BLOCKS EMPTY_BLOCKS

  

  A                              

  注意:TRUNCATE命令回收了由delete命令產生的空閒空間假如表原有使用TRUNCATE後該表分配的空間降為為了保留由delete命令產生的空閒空間可以使用TRUNCATE TABLE TEST REUSE STORAGE用此命令後該表還會是原先的

  HWM的一些特性

   oracle用HWM來界定一個段中使用的塊和未使用的塊

  當我們創建一個表:A時ORACLE就會為這個對象分配一個段在這個段中即使我們未插入任何記錄也至少有一個區(bit也就是個塊)被分配第一個區的第一個塊就稱為段頭(SEGMENT HEADE)段頭中就儲存了一些信息基中HWM的信息就存儲在此此時因為第一個區的第一塊用於存儲段頭的一些信息雖然沒有存儲任何實際的記錄但也算是被使用此時HWM是位於第個塊當我們不斷插入數據到A後個塊已經放不下後面新插入的數據此時ORACLE將高水位之上的塊用於存儲新增數據同時HWM本身也向上移也就是說當我們不斷插入數據時HWM會不斷上移這樣在HWM之下的就表示使用過的塊HWM之上的就表示已分配但從未使用過的塊

   HWM在插入數據時當現有空間不足而進行空間的擴展時會向上移但刪除數據時不會往下移

  這就好比是水庫的水位當漲水時水位往上移當水退出後最高水位的痕跡還是清淅可見

  刪除數據後便存在浪費的空間ORACLE 不會釋放空間以供其他對象使用有一條簡單的理由由於空間是為新插入的行保留的並且要適應現有行的增長被占用的最高空間稱為最高使用標記 (HWM)

   HWM的信息存儲在段頭當中

  HWM本身的信息是儲存在段頭在段空間是手工管理方式時ORACLE是通過FREELIST(一個單向鏈表)來管理段內的空間分配在段空間是自動管理方式時(ASSM)ORACLE是通過BITMAP來管理段內的空間分配

   ORACLE的全表掃描是讀取高水位標記(HWM)以下的所有塊

  當用戶發出一個全表掃描時ORACLE 始終必須從段一直掃描到 HWM即使它什麼也沒有發現該任務延長了全表掃描的時間

  采用TRUNCATE語句刪除一個表的數據的時候類似於重新建立了表不僅把數據都刪除了還把HWM給清空恢復為

   當用直接路徑插入行時 — 例如通過直接加載插入(用 APPEND 提示插入)或通過 SQL*LOADER 直接路徑 — 數據塊直接置於 HWM 之上它下面的空間就浪費掉了

  在手動段空間管理(Manual Segment Space Management)中段中只有一個HWM但是在Oracle i Release才添加的自動段空間管理(Automatic Segment Space Management)中又有了一個低HWM的概念出來為什麼有了HWM還又有一個低HWM呢這個是因為自動段空間管理的特性造成的在手段段空間管理中當數據插入以後如果是插入到新的數據塊中數據塊就會被自動格式化等待數據訪問而在自動段空間管理中數據插入到新的數據塊以後數據塊並沒有被格式化而是在第一次訪問這個數據塊的時候才格式化這個塊所以我們又需要一條水位線用來標示已經被格式化的塊這條水位線就叫做低HWM一般來說低HWM肯定是低於等於HWM的

  額外擴展

  [TEST@orcl] SQL>delete from c;

  [TEST@orcl] SQL>alter table c shrink space;

  alter table c shrink space

  *

  第 行出現錯誤:

  ORA: ROW MOVEMENT is not enabled

  [TEST@orcl] SQL>alter table c enable row movement;

  表已更改

  [TEST@orcl] SQL>alter table c shrink space;

  表已更改

  [TEST@orcl] SQL>analyze table c compute statistics;

  [TEST@orcl] SQL>select table_nameblocksempty_blocks from user_tables where table_name=C;

  TABLE_NAME     BLOCKS EMPTY_BLOCKS

  

  C                              

   修正ORACLE表的高水位線

  在ORACLE中執行對表的刪除操作不會降低該表的高水位線而全表掃描將始終讀取一個段(extent)中所有低於高水位線標記的塊如果在執行刪除操作後不降低高水位線標記則將導致查詢語句的性能低下

  下面的方法都可以降低高水位線標記

  () 執行表重建指令 alter table table_name move;

  在線轉移表空間ALTER TABLE MOVE TABLESPACE

  當你創建了一個對象如表以後不管你有沒有插入數據它都會占用一些塊ORACLE也會給它分配必要的空間同樣用ALTER TABLE MOVE釋放自由空間後還是保留了一些空間給這個表

  ALTER TABLE MOVE 後面不跟參數也行不跟參數表還是在原來的表空間Move後記住重建索引如果以後還要繼續向這個表增加數據沒有必要move只是釋放出來的空間只能這個表用其他的表或者segment無法使用該空間

  () 執行alter table table_name shrink space;

  注意此命令為Oracle g新增功能再執行該指令之前必須允許行移動 alter table table_name enable row movement;

  如果要同時壓縮表的索引:ALTER TABLE TEST_TAB SHRINK SPACE CASCADE

  () 復制要保留的數據到臨時表tdrop原表然後rename臨時表t為原表

  () 用邏輯導入導出: Emp/Imp

  () Alter table table_name deallocate unused

  注這證明DEALLOCATE UNUSED為釋放HWM上面的未使用空間但是並不會釋放HWM下面的自由空間也不會移動HWM的位置

  () 盡量使用truncate


From:http://tw.wingwit.com/Article/program/Oracle/201311/17321.html
  • 上一篇文章:

  • 下一篇文章:
  • Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.